2010-04-05 12 views
5

Estoy buscando ideas sobre cómo implementar un sistema de estilo Mixin/Trait en AS3.Implementación de Mixin o Trait en AS3?

Quiero ser capaz de componer varias clases juntas en un solo objeto. Por supuesto, esta no es una función de nivel de idioma de AS3, pero espero que haya alguna forma de hacerlo utilizando técnicas basadas en prototipos o tal vez algunos pirateo de códigos que creo que AsMock utiliza para implementar su funcionalidad.

Un ejemplo de Java existente es Qi4J donde el usuario define las interfaces que el marco Qi4j implementa en base a las etiquetas de metadatos y la codificación por convención.

¿Alguien tiene alguna idea sobre cómo conseguir que el concepto Mixin/Trait funcione dentro de AS3?

Respuesta

7

Cero soluciones presentadas en esto, así que busqué algunos métodos. Hay ECMA script style mixins agregando métodos definidos en otros objetos al prototipo de objetos base. Pero esto significa que las ventajas de la tipificación estática ya no existen.

Estaba buscando una solución que no dejara de lado el sistema de tipo estático. Sabía que ASMock utilizaba inyección de código para crear clases de proxy. Hace unos días pirateé alrededor de ASMock y se me ocurrió una posible solución implementada mediante la creación de una clase con clases compuestas (a través de la inyección de código de bytes).

De los usuarios punto de vista se trata de definir el objeto que usa mixins a través de muchas interfaces:

public interface Person extends RoomObject, Moveable 

public interface RoomObject 
{ 
    function joinRoom(room:Room):void 
    function get room():Room 
} 

public interface Moveable 
{ 
    function moveTo(location:Point):void 
    function get location():Point 
} 

A continuación, definir clases para representar estas interfaces:

public class MoveableImpl implements Moveable 
{ 
    private var _location:Point = new Point() 
    public function get location():Point { return _location } 

    public function move(location:Point):void 
    { 
     _location = location.clone() 
    } 
} 

public class RoomObjectImpl implements RoomObject 
{ 
    private var _room:Room 
    public function get room():Room { return _room } 

    public function joinRoom(room:Room):void 
    { 
     _room = room 
    } 
} 

En una situación normal, donde desea componer las clases que escribiría:

public class PersonImpl implements Person 
{ 
    private var _roomObject:RoomObject = new RoomObjectImpl() 

    private var _moveable:Moveable = new MoveableImpl() 

    public function get room():Room { return _roomObject.room } 

    public function joinRoom(room:Room):void { _roomObject.joinRoom(room) } 

    public function get location():Point { return _moveable.location } 

    public function move(location:Point):void { _moveable.move(location) } 
} 

Esto se escribe fácilmente usando código debido a su diseño regular. Y eso es exactamente lo que hace mi solución, al inyectar el bytecode equivalente en una nueva clase. Con este sistema de inyección de código de bytes podemos crear un objeto Person, así:

public class Main 
{ 
    private var mixinRepo:MixinRepository = new MixinRepository() 

    public function Main() 
    { 
     with(mixinRepo) 
     { 
      defineMixin(RoomObject, RoomObjectImpl) // associate interfaces with concreate classes 
      defineMixin(Moveable, MoveableImpl) 
      defineBase(Person) 
      prepare().completed.add(testMixins) // the injection is a async process, just liek in ASMock 
     } 
    } 

    private function testMixins():void 
    { 
     var person:Person = mixinRepo.create(Person) 
     var room:Room = new Room('room you can play in') 

     person.joinRoom(room) 
     trace('person.room:', person.room) 

     person.move(new Point(1, 2)) 
     trace('person.location:', person.location) 
    } 
} 

Por el momento este sistema es una prueba de concepto y por lo tanto es muy básico y quebradizo. Pero muestra que es posible acercarse al sistema de estilo Scala mixin/traits de AS3. He creado un github project para guardar el código si alguien está interesado en ejecutar la solución y echar un vistazo a cómo se hizo.

Un ejemplo más completo se da en el proyecto wiki.

+0

me di cuenta de que sus enlaces no funcionaban, así que les he actualizado. –

+0

Bien, gracias Andrew;) –

1

Mira aquí, esto funciona, se mezcla en métodos y es simple.

http://github.com/specialunderwear/as3-mixin

o, y funciona cuando se compila en modo AS3.

+0

Buena idea, voy a probarlo en mi próximo proyecto as3. –

+0

Desafortunadamente, hacerlo de esa manera no ayuda al verificador de tipos :(. –

+0

Dado que mixins son clases extranjeras, que no tienen ninguna influencia en el tipo de la clase en la que estás mezclando métodos, esa es una característica de mixins, no de esta implementación en particular. Si desea que el tipo de su clase defina su funcionalidad (única), nunca debe usar mixins. – specialunderwear