5

AS3 でMixin/Traitスタイル システムを実装する方法についてのアイデアを探しています。

多数のクラスをまとめて単一のオブジェクトに構成できるようにしたいと考えています。もちろん、これは AS3 の言語レベルの機能ではありませんが、プロトタイプ ベースの手法や、AsMock がその機能を実装するために使用すると思われるバイトコード ハッキングを使用してこれを行う方法があることを願っています。

既存の Java の例はQi4Jであり、ユーザーは Qi4j フレームワークがメタデータ タグと規約によるコーディングに基づいて実装するインターフェイスを定義します。

Mixin/Trait の概念を AS3 内で機能させる方法について何かアイデアはありますか?

4

3 に答える 3

7

これに関する解決策はありませんでしたので、いくつかの方法を調べました。基本オブジェクトのプロトタイプに他のオブジェクトで定義されたメソッドを追加することにより、ECMA スクリプト スタイルの mixinが存在します。しかし、これは静的型付けの利点がなくなったことを意味します。

静的型システムを回避しないソリューションを探していました。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)
    }
}

現時点では、このシステムは概念実証であるため、非常に基本的で脆弱です。しかし、Scala mixin/traits スタイル システムに AS3 を近づけることが可能であることを示しています。誰かがソリューションを実行して、それがどのように行われたかを調べることに興味がある場合は、コードを保持するgithubプロジェクトを作成しました。

より完全な例は、プロジェクトのwikiにあります。

于 2010-04-18T22:03:17.077 に答える
1

ここを見てください、これは機能し、メソッドを組み合わせて、シンプルです。

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

o、as3モードでコンパイルすると機能します。

于 2010-10-15T21:36:55.433 に答える
1

Realaxy でこれを見つけました -- http://realaxy.com/

于 2012-04-03T04:47:05.877 に答える