Publicado em 18.Fev.2010 por Rafael Martinelli
Categorias: ActionScript, Flex, Programação
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
Aeee, muito bom!! Já vi muita “magia negra” pra fazer isso, mas essa é a melhor maneira com certeza!! ;D
É isso mesmo Gil. Também esqueci de comentar que é possível comparar os objetos:
if (Model.getInstance().state == StateEnum.EDITING)
{
bla bla bla bla
}
Na verdade o construtor statico no AS3 não precisa das chaves “{“, “}”. Pode escrever direto na classe mesmo. Apesar que fica bem feio.
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;
}
}
}
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
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.
Estranho, eu jah fiz isso… vou procurar aqui no meio dos meus papiros…
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…..
=(
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.
Hrm…. provavelmente seja isso então =/
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
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.
Henriqueeeee, please share it with us! =D
Fiquei curioso, penso q deve ter ido pelo lado do BeanProxy… foi?
[]s
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
Top-notch info it is really. We’ve been searching for this update
Deixe Seu Comentário