Typesafe Enum em Action Script 3

O screencast abaixo é bem simples, porém muito eficiente para proteger o seu código. É importante ressaltar que isso tudo é necessário, pois o Action Script 3 não possui construtor privado e muito menos a implementação nativa de Enum.


15 comentários

  1. André Gil em 18.fev.10 às 12:57 pm

    Aeee, muito bom!! Já vi muita “magia negra” pra fazer isso, mas essa é a melhor maneira com certeza!! ;D

  2. Rafael Martinelli em 18.fev.10 às 1:16 pm

    É isso mesmo Gil. Também esqueci de comentar que é possível comparar os objetos:

    if (Model.getInstance().state == StateEnum.EDITING)
    {
    bla bla bla bla
    }

  3. Rafaelsc em 18.fev.10 às 1:22 pm

    Na verdade o construtor statico no AS3 não precisa das chaves “{“, “}”. Pode escrever direto na classe mesmo. Apesar que fica bem feio.

  4. Marvin Froeder em 18.fev.10 às 4:25 pm

    Sugestão para deixar a validação em tempo de compilação:

    package
    {

    public class StateEnum
    {

    public static const A:StateEnum = new StateEnum( new Name( “a” ) );
    public static const B:StateEnum = new StateEnum( new Name( “b” ) );
    public static const C:StateEnum = new StateEnum( new Name( “c” ) );

    private var _name:String;

    public function StateEnum( name:Name )
    {
    this._name = name._name;
    }

    override public function toString():String
    {
    return _name;
    }

    }

    class Name
    {

    private var _name:String;

    public function Name( name:String )
    {
    this._name = name;
    }
    }
    }

  5. Marvin Froeder em 18.fev.10 às 4:26 pm

    O exemplo acima pode ser combinado com o exemplo apresentado. O grande problem é a quantidade de código necessária… afinal de contas, em java são 3 linhas de código =D

  6. Rafael Martinelli em 18.fev.10 às 7:23 pm

    Marvin, obrigado pelo comentário. Eu já tinha tentado usar esta abordagem, mas ela não funciona. Faria todo o sentido, mas infelizmente ela não funciona. Veja o erro:

    [SWF] Developer:workspace:TypeSafeEnum:bin-debug:TypeSafeEnum.swf – 652,560 bytes after decompression
    TypeError: Error #1115: StateEnum.as$0::Name is not a constructor.
    at StateEnum$cinit()
    at global$init()[/Developer/workspace/TypeSafeEnum/src/StateEnum.as:4]
    at TypeSafeEnum/changeToUpdateState()[/Developer/workspace/TypeSafeEnum/src/TypeSafeEnum.mxml:10]
    at TypeSafeEnum/___TypeSafeEnum_Button1_click()[/Developer/workspace/TypeSafeEnum/src/TypeSafeEnum.mxml:23]

    Pelo que eu entendi, não se pode chamar um construtor de uma inner class de um atributo estático da classe pai. A única explicação plausível para isso é que a inner class provavelmente será carregada após o carregamento da classe pai e de seus atributos estáticos.

    Dessa maneira (infelizmente), a único jeito de se implementar o pattern TypeSafe Enum é como exemplifiquei no screencast.

    Queria que fosse como no Java também :)

    Abraço.

  7. Marvin Froeder em 18.fev.10 às 8:50 pm

    Estranho, eu jah fiz isso… vou procurar aqui no meio dos meus papiros…

  8. Marvin Froeder em 18.fev.10 às 9:24 pm

    Olha, realmente, não funciona… mas acho que isso funcinava na época do flex 2…
    http://www.ericfeminella.com/blog/2007/01/16/pseudo-abstract-classes-in-as3/
    Esse pattern eu usei algumas vezes…

    Ou é alguma mudança no flex ou no flashplayer…..

    =(

  9. Rafael Martinelli em 19.fev.10 às 8:37 am

    Marvin, no link que você enviou o objetivo é outro e deve funcionar. Como eu disse, o problema é criar uma instância da inner class a partir de um atributo estático.

    Abraço.

  10. Marvin Froeder em 19.fev.10 às 1:07 pm

    Hrm…. provavelmente seja isso então =/

  11. Mario Junior em 24.fev.10 às 12:02 am

    Minha unica “birra” com a falta de Enums é em relação a serialização deles. Já fiz um teste extendendo a classe AMFEndpoint no BlazeDS e funciona, mas é uma modificacao bem “grandinha” só pra ter suporte a isso. Outra alternativa seria criando uma wrapper a partir da classe BeanProxy, mas ainda nao tentei (deve ser uma implementacao bme mais limpa). Além do mais, seria necessário um tipo Enum “proprio” no lado do flex, mas isso seria fácil de jogar em algum utils.swc.

    (sobre estender o AMFEndpoint, a ideia original vem da Farata Systems: http://is.gd/931px)

    []s

  12. Rafael Martinelli em 24.fev.10 às 2:42 am

    Mario, obrigado pelo comentário. Nosso amigo Henrique (colega nosso de DClick), alterou a serialização do Blaze e usamos em todos os projetos. Já cobrei ele de fazer um screencast sobe isso e disponibilizar o código. Tem que fazer uma implementação no Flex também.

    Me ajude a “encher” a paciência dele para fazer o screencast :)

    Abraço.

  13. Mario Junior em 24.fev.10 às 3:50 pm

    Henriqueeeee, please share it with us! =D
    Fiquei curioso, penso q deve ter ido pelo lado do BeanProxy… foi?

    []s

  14. Marvin Froeder em 12.abr.10 às 11:33 am

    Opa Rafael,

    Finalmente eu achei o código onde aquele negócio do construtor funciona…. na real eu tinha esquecido de uma coisinha, eu tinha feito usando uma classe pai…. as enum extendem de uma EnumBase e nessa EnumBase você coloca essa class Name ou como queira chamar….

    package b
    {

    public class EnumBase {

    private var _name:String;

    function EnumBase( name:String, namer:* ) {
    if ( !( namer is namer ) ) { throw new Error(); }
    _name = name;
    }

    public function get name():String { return _name; }

    protected static function get namerInstance():namer { return new namer(); }

    }
    }

    class namer{}

    A enum vai ficar assim….
    public class StateEnum extends EnumBase
    {
    public static const A:StateEnum = new StateEnum( “a”, namerInstance );
    public static const B:StateEnum = new StateEnum( “b”, namerInstance );
    public static const C:StateEnum = new StateEnum( “c”, namerInstance );

    function StateEnum( value:String, namerInst:* )
    {
    super( value, namerInst );
    }

    }

    Claro nada impede de se passar null no construtor (ou qq outra coisa) daí só dá pra pegar o erro em runtime…. mas fica menos obvio para fazer de forma não certa =D

    VELO

  15. kurt rambis contract timberwolves em 16.mar.12 às 11:22 am

    Top-notch info it is really. We’ve been searching for this update

Deixe Seu Comentário