我正在寻找关于如何在AS3中实现Mixin/Trait风格系统的想法。
我希望能够将多个类组合到一个对象中。当然,这不是AS3的语言级特性,但我希望有一些方法可以使用基于原型的技术来实现这一点,或者我相信AsMock使用一些字节码黑客来实现它的功能。
现有的一个示例是Qi4J,其中用户根据元数据标记和编码约定定义Qi4j框架实现的接口。
有没有人有关于如何在AS3中使用Mixin/Trait概念的想法?
发布于 2010-04-19 06:03:17
在这个问题上出现了零解决方案,所以我研究了一些方法。通过将定义在其他对象上的方法添加到基本对象原型中,可以实现ECMA script style mixins。但这意味着静态类型的优势已经消失。
我正在寻找一种不回避静态类型系统的解决方案。我知道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接近的Scala混合/特征风格系统是可能的。我做了一个github project,如果有人对运行解决方案感兴趣,并了解它是如何完成的,就可以使用它来保存代码。
在项目wiki上给出了一个更完整的示例。
发布于 2010-10-16 05:36:55
看这里,这是可行的,混合了方法,而且很简单。
http://github.com/specialunderwear/as3-mixin
o,当您在as3模式下编译时,它可以工作。
发布于 2012-04-03 12:47:06
我在Realaxy找到了这个-- http://realaxy.com/
https://stackoverflow.com/questions/2577574
复制相似问题