Nov 19

Zapewne każdy flash developer ma swój sposób na wczytywanie flash varów. Ja chciałbym przedstawić ten, z którego od jakiegoś czasu korzystam, oparty na wzorcach projektowych Multiton (Multiton Pattern) oraz Strategii.

Rozwiązanie składa się z dwóch klas FlashVars i AbstractFlashVarsProvider oraz interfejsu IFlashVarsProvider.

Klasa FlashVars działa jako Multiton i pozwala tworzyć przy pomocy statycznej metody getInstance(name : String , flashVarsProviderClass : Class) instancje samej siebie, pobierając w argumentach nazwę nowego obiektu oraz nazwę klasy, która dostarczy schemat flash var’ów. FlashVars referencje każdej swojej instancji zapisuje w polu statycznej tablicy __instances, do której dostęp jest możliwy poprzez FlashVars.getInstances() : Array.

Natomiast AbstractFlashVarsProvider jest abstrakcyjną klasą, po której dziedziczą wszystkie klasy, dostarczające nazwy flash var’ów i ich defaultowe wartości. Implementuje ona interfejs IFlashVarsProvider.

Poniżej znajduje się kod źródłowy poszczególnych elementów składowych.

package pl.rafalbociek.utils.flashvars
{
    import flash.display.Stage;
    import flash.utils.getQualifiedClassName;  
   
    /**
     * @author Rafal Bociek 2009
     *
     * Klasa obslugujaca pobieranie flash var'ow.
     *
     * ( Multiton pattern )
     */

     
    public class FlashVars
    {
        /**
         * Wlasciwosci prywatne
         */

       
        // Referencja do obiektu, ktory dostarcza konfiguracje flash var'ow
       
        private var __flashVarsProvider : AbstractFlashVarsProvider;
       
       
       
        // Nazwa/klucz instancji multiton'a
       
        private var __name              : String;                              
       
       
       
        // Enforcer blokujacy wywolywanie konstruktora spoza tego pakietu
       
        private var __sE                : $MultitonEnforcer;                     
       
       
       
        /**
         * Statyczne wlasciwosci prywatne
         */

       
        // Tablica instancji multiton'a
       
        private static var __instances  : Array = new Array();                 


       
        /**
         * Funkcja tworzy nowy obiekt FlashVars.
         * Konstruktor moze byc wywolany tylko poprzez getInstance()
         * @param name Nazwa/klucz tworzonej instancji
         * @param flashVarsProviderClass Klasa provider'a flash var'ow
         * @param mE Referencja do enforcer'a
         */

         
        public function FlashVars(name : String , flashVarsProviderClass : Class,
                                                mE : $MultitonEnforcer) : void
        {
            __flashVarsProvider = new flashVarsProviderClass();
           
            __sE    = mE;
            __name  = name;
        }



        /**
         * Funkcja zwraca instancje multiton'a o okreslonym kluczu.
         * @param key Nazwa instancji multiton'a.
         * @param flashVarsProviderClass Klasa, ktora dostarcza
         * konfiguracje flash var'ow.
         */

         
        public static function getInstance ( key : String ,
                                    flashVarsProviderClass : Class ) : FlashVars
        {
            var instance : FlashVars = __instances[key];
           
            if(instance == null)
            {
                instance = new FlashVars( key , flashVarsProviderClass ,
                                            new $MultitonEnforcer() );
               
                __instances[key] = instance;
            }
           
            return instance;
        }


       
        /**
         * Funkcja pobiera flash var'y z okreslonego stage'a.
         */

       
        public function loadVariables(stage : Stage) : void
        {
            var instance : FlashVars = __instances[__name];
           
            if(instance == null){}
            else
            {
                __flashVarsProvider.loadFlashVars(stage);
            }
        }



        /**
         * Wyswietla wszystkie flash var'y, przechowywane w danej instancji;
         */

         
        public function describeFlashVars() : String
        {
            var str : String = '';
            str += 'n| FLASH VARS: ';
            str += 'n|';
           
            for (var fvName : String in __flashVarsProvider.getFlashVars())
            {
                str += 'n| NAME: ' + fvName + ' VALUE: ' +
                __flashVarsProvider.getFlashVars()[fvName];
            }

            str += 'n|n';
           
            return str;
        }



        /**
         * Funkcja zwraca asocjacyjna tablice z obiektu,
         * ktory dostarcza flash var'y.
         */

         
        public function getData() : Array
        {          
            return (__flashVarsProvider != null)?
            __flashVarsProvider.getFlashVars() : null;
        }


       
        /**
         * Funkcja zwraca tablice instancji multiton'a.
         */

         
        public static function getInstances () : Array
        {
            return __instances;
        }


       
        /**
         * Funkcja zwraca nazwe konkretnej instancji multiton'a.
         */

         
        public function getName () : String
        {
            return __name;
        }


       
        /**
         * Funkcja zwraca ciag znakow, opisujacy konkretna instancje multiton'a.
         */

         
        public function toString () : String
        {
            return '| FLASVARS MULTITON | [ name: ' + getName() +
            ' | provider: ' + getQualifiedClassName(__flashVarsProvider) + ' ]';
        }
    }
}
internal class $MultitonEnforcer
{
    public function $MultitonEnforcer()
    {
       
    }
}

FlashVars.as

package pl.rafalbociek.utils.flashvars.interfaces
{
    import flash.display.Stage;    

    /**
     * @author Rafal Bociek 2009
     *
     * Interfejs klas,
     * dostarczajacych schematy flash var'ow.
     */

     
    public interface IFlashVarsProvider
    {
        function loadFlashVars(stage : Stage)   : void;
        function getFlashVars()                 : Array;  
    }
}

IFlashVarsProvider.as

package pl.rafalbociek.utils.flashvars
{
    import pl.rafalbociek.utils.Output;
    import pl.rafalbociek.utils.flashvars.interfaces.IFlashVarsProvider;
   
    import flash.display.Stage;    

    /**
     * @author Rafal Bociek 2009
     *
     * Klasa abstrakcyjna, po ktorej dziedzicza wszystkie klasy,
     * dostarczajace konfiguracje flash var'ow.
     */

    public class AbstractFlashVarsProvider implements IFlashVarsProvider
    {
        /**
         * Tablica asocjacyjna klucz-wartosc.
         * Kluczem jest nazwa flas var'a a wartoscia dane flash var'a.
         */

        protected var _flashVars    : Array;
       
        public function AbstractFlashVarsProvider ()
        {
            /**
             * Konstruktor powinien byc nadpisany w klasie
             * dziedzicacej po AbstractFlashVarsProvider.
             *
             * W konstruktorze powinny byc zainicjowane default'owe
             * wartosci flash varow, np.
             *
             * _flashVars = new Array();
             *
             * _flashVars[FV_1] = 'default value of flash var 1';
             * _flashVars[FV_2] = 'default value of flash var 2';
             * _flashVars[FV_3] = 'default value of flash var 3';
             */

        }

        public function loadFlashVars ( stage : Stage ) : void
        {
            if(_flashVars != null)
            {
                if( stage.loaderInfo.parameters != null )
                {
                    try
                    {
                        for (var fvName : String in _flashVars)
                        {
                            _flashVars[fvName] =
                            (stage.loaderInfo.parameters[fvName] != null) ?
                            stage.loaderInfo.parameters[fvName] :
                            _flashVars[fvName];
                        }
                    }
                    catch ( e : Error )
                    {
                        Output.println('[ Wystapil blad przy probie'+
                        ' wczytania flash var\'ow! ]');
                       
                        Output.println('-----------------------------'+
                        '------------------------');
                       
                        Output.println( e.message );
                    }
                }
            }
        }

        public function getFlashVars () : Array
        {
            return _flashVars;
        }
    }
}

AbstractFlashVarsProvider.as

Jak skorzystać z tego sposobu wczytywania? Bardzo prosto…
Tworzę przykładową klasę SampleFlashVarsProvider1. Dziedziczy ona po AbstractFlashVarsProvider i przejmuje mechanizmy pobierania flash var’ów i pracy z nimi. Moim zadaniem jest tylko zdefiniowanie nazw wczytywanych zmiennych, ich początkowych wartości oraz nazwy ‘dostawcy’ danych (PROVIDER_NAME).

package pl.rafalbociek.utils.flashvars
{
    /**
     * @author Rafal Bociek 2009
     *
     * Klasa przechowujaca nazwy flash var'ow
     * oraz ich default'owe wartosci.
     */

     
    public class SampleFlashVarsProvider1 extends AbstractFlashVarsProvider
    {
        public static const PROVIDER_NAME : String = 'sampleFlashVarsProvider1';
       
        /**
         * Nazwy flash var'ow
         */

         
        public static const SAMPLE_FLASHVAR_1   : String = 'sampleFlashVar1';
        public static const SAMPLE_FLASHVAR_2   : String = 'sampleFlashVar2';
        public static const SAMPLE_FLASHVAR_3   : String = 'sampleFlashVar3';
        public static const SAMPLE_FLASHVAR_4   : String = 'sampleFlashVar4';
        public static const SAMPLE_FLASHVAR_5   : String = 'sampleFlashVar5';
       
        /**
         * Konstruktor
         */

       
        public function SampleFlashVarsProvider1 ()
        {
            /**
             * Default'owe flash var'y
             */

           
            _flashVars = new Array();
           
            _flashVars[SAMPLE_FLASHVAR_1] = 'defaultValueOfSampleFlashVar1';
            _flashVars[SAMPLE_FLASHVAR_2] = 'defaultValueOfSampleFlashVar2';
            _flashVars[SAMPLE_FLASHVAR_3] = 'defaultValueOfSampleFlashVar3';
            _flashVars[SAMPLE_FLASHVAR_4] = 'defaultValueOfSampleFlashVar4';
            _flashVars[SAMPLE_FLASHVAR_5] = 'defaultValueOfSampleFlashVar5';
        }
    }
}

SampleFlashVarsProvider1.as

Pozostało już tylko przetestowanie mechanizmu.

package pl.rafalbociek.utils.flashvars
{
    import pl.rafalbociek.utils.Output;
    import flash.display.Sprite;
   
    /**
     * @author Rafal Bociek 2009
     *
     * Klasa pokazujaca sposob korzystania z klasy FlashVars.
     *
     * ( The example of using FlashVars class. )
     */

     
    public class FlashVarsTestDC extends Sprite
    {
       
        /**
         * Konstruktor
         */

       
        public function FlashVarsTestDC ()
        {          
            Output.debugEnabled = true;
           
            // Tworzę instancję FlashVars o nazwie
            // sampleFlashVarsProvider1
           
            var fvCfg1 : FlashVars = FlashVars.getInstance  (
                                        SampleFlashVarsProvider1.PROVIDER_NAME ,
                                        SampleFlashVarsProvider1
                                    );
           
            // Wczytuje dane flash var'ow
                                           
            fvCfg1.loadVariables(stage);
           
           
            // Wyswietlam zawartosc wczytanych flash var'ow
           
            Output.println( fvCfg1.describeFlashVars( ) );
           
           
            // Pobieram testowo wartosc flash var'a
            // SampleFlashVarsProvider1.SAMPLE_FLASHVAR_3
           
            Output.println( SampleFlashVarsProvider1.SAMPLE_FLASHVAR_3 +
            ' = '+fvCfg1.getData()[SampleFlashVarsProvider1.SAMPLE_FLASHVAR_3]);
        }
    }
}

FlashVarsTestDC.as

Mimo, że na pierwszy rzut oka duża ilość kodu może odstraszyć, dużą zaletą jest łatwość tworzenia różnych konfiguracji flash varów poprzez dziedziczenie po AbstractFlashVarsProvider oraz dostęp do wczytanych danych statycznymi metodami klasy FlashVars. Klasa FlashVars pilnuje także by nie tworzone były zbędne referencje do jej instancji.

Oczywiście w przypadku wczytywania jednego flash var’a nie ma sensu tego typu rozwiązanie, ale w większych projektach sprawdza się bardzo dobrze i je polecam.

Źródła do pobrania stąd.