5

我正在寻找有关如何在 AS3 中实现Mixin/Trait样式系统的想法。

我希望能够将多个类组合成一个对象。当然,这不是 AS3 的语言级功能,但我希望可能有某种方法可以使用基于原型的技术或我相信 AsMock 用来实现其功能的一些字节码黑客技术来做到这一点。

现有的 Java 示例是Qi4J,其中用户定义 Qi4j 框架根据元数据标签和约定编码实现的接口。

有人对如何在 AS3 中使用 Mixin/Trait 概念有任何想法吗?

4

3 回答 3

7

对此提出了零解决方案,因此我研究了一些方法。通过将其他对象上定义的方法添加到基础对象原型中,有ECMA 脚本风格的混合。但这意味着静态类型的优势消失了。

我正在寻找一种不回避静态类型系统的解决方案。我知道ASMock使用字节码注入来创建代理类。在过去的几天里,我研究了ASMock,并想出了一个可能的解决方案,它通过创建一个具有组合类的类(通过字节码注入)来实现。

从用户的角度来看,这涉及通过许多接口定义使用 mixin 的对象:

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 的 Scala mixin/traits 风格系统。如果有人有兴趣运行解决方案并探索它是如何完成的,我已经制作了一个 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 回答