Zero-Lösungen auf dieser vorgestellt, so habe ich ein paar Methoden untersucht. Es gibt ECMA script style mixins, indem Methoden, die für andere Objekte definiert sind, zum Prototyp der Basisobjekte hinzugefügt werden. Aber das bedeutet, dass die Vorteile der statischen Typisierung weg sind.
Ich war auf der Suche nach einer Lösung, die das statische System nicht umgangen hat. Ich wusste, dass ASMock Bytecode-Injektion verwendet, um Proxy-Klassen zu erstellen. Ich habe in den letzten paar Tagen um ASMock gehackt und eine mögliche Lösung gefunden, die implementiert wurde, indem eine Klasse mit zusammengesetzten Klassen erstellt wurde (durch Bytecode-Injektion).
Von den Nutzern Sicht zeigen diese beinhaltet das Objekt definieren, die Mixins durch viele Schnittstellen verwendet:
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
}
Dann definieren Sie Klassen diese Schnittstellen zu repräsentieren:
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
}
}
In einer normalen Situation, in der Sie möchten Klassen zusammenstellen, die Sie schreiben würden:
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) }
}
Dies ist aufgrund des regulären Layouts leicht mit Code zu schreiben. Und genau das macht meine Lösung, indem ich den äquivalenten Bytecode in eine neue Klasse einspeise. Mit diesem Bytecode-Einspritzsystems können wir eine Person Objekt wie so erstellen:
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)
}
}
Im Moment ist dieses System eine Proof of Concept und ist daher sehr einfach und spröde. Aber es zeigt, dass es möglich ist, zu einem Scala Mixin/Traits Style System zu AS3 zu kommen. Ich habe eine Github project gemacht, um den Code zu halten, wenn jemand daran interessiert ist, die Lösung zu starten und herumzustochern, wie es gemacht wurde.
Ein ausführlicheres Beispiel wird zum Projekt wiki gegeben.
ich, dass Ihre Links bemerkt wurden nicht funktioniert, also habe ich sie aktualisiert. –
Schön, danke Andrew;) –