Внедрение Mixin или Trait в AS3? - PullRequest
5 голосов
/ 05 апреля 2010

Я ищу идеи о том, как реализовать систему типа Mixin / Trait в AS3.

Я хочу иметь возможность объединить несколько классов в один объект. Конечно, это не особенность языкового уровня AS3, но я надеюсь, что, возможно, есть какой-то способ сделать это, используя методы, основанные на прототипах, или, возможно, некоторый взлом байт-кода, который, как я считаю, использует AsMock для реализации своей функциональности.

Существующим примером Java является Qi4J , где пользователь определяет интерфейсы, которые реализует платформа Qi4j, на основе тегов метаданных и кодирования в соответствии с соглашением.

Есть ли у кого-нибудь идеи о том, как заставить концепцию Mixin / Trait работать в AS3?

Ответы [ 3 ]

7 голосов
/ 19 апреля 2010

Ноль решений представлено на этом, поэтому я рассмотрел несколько методов. Существуют миксины стилей сценариев ECMA , добавляющие методы, определенные для других объектов, в прототип базовых объектов. Но это означает, что преимущества статической типизации исчезли.

Я искал решение, которое не обошло бы статическую систему типов. Я знал, что ASMock использовал внедрение байт-кода для создания прокси-классов. За последние несколько дней я взломал ASMock и нашел возможное решение, реализованное путем создания класса с составными классами (с помощью внедрения байт-кода).

С точки зрения пользователей это включает определение вашего объекта, который использует миксины через множество интерфейсов:

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 
}

Затем вы определяете классы для представления этих интерфейсов:

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
    }
}

В обычной ситуации, когда вы хотите создавать классы, вы должны написать:

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) }
}

Это легко написать с помощью кода из-за его обычного расположения. И это именно то, что делает мое решение, вводя эквивалентный байт-код в новый класс. С помощью этой системы внедрения байт-кода мы можем создать объект Person следующим образом:

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)
    }
}

На данный момент эта система является доказательством концепции и поэтому является очень простой и хрупкой. Но это показывает, что к AS3 можно приблизиться к системе стилей mixin / traits от Scala. Я создал проект github для хранения кода, если кто-то заинтересован в запуске решения и изучает, как оно было сделано.

Более полный пример приведен для проекта wiki .

1 голос
/ 03 апреля 2012

Я нашел это в Realaxy - http://realaxy.com/

1 голос
/ 16 октября 2010

Посмотрите здесь, это работает, смешивается в методах и просто.

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

o, и это работает при компиляции в режиме as3.

...