Non sono sicuro di come implementare questo modello per creare diverse aure.
Una Hase per prendere una decisione, sia la progettazione di un Aura
constructor-/fabbrica a base di e non tagliare delegazione prototipale al fine di essere in grado di andare più tardi per più variazioni aura facendo uso di eredità, o di decomposizione di un a tutti gli effetti Aura
in vari mix, ognuno con un insieme ben definito di comportamento a grana fine.
L'approccio basato esempio aura più propably diventa complicato in cui si basa su inoltro se uno sta per "aggiungere" un'istanza aura (che nell'esempio dato è in grado di evento dispacciamento) su un personaggio ... MyCharacter.addAura(new MyAura(any, args))
... Il metodo addAura
del costruttore di un giocatore deve essere implementato in un modo che tiene già conto che l'aura di per sé presenta i metodi di destinazione dell'evento. Quindi questo codice deve venire con una propria soluzione per l'inoltro al fine di abilitare un giocatore di dispiegamento di eventi per il tempo che porta un'aura lungo.
La prossima data bollito giù, ma ad esempio (s) di lavoro potrebbe puntare a quello che è appena stato detto ...
var Player = (function() { // sort of factory module implementation.
var
// ...
// ...
addAura = function (player, aura) { // simplified forwarding or delegation.
// ...
player.on = function (type, handler) {
aura.on(type, handler); // forwarding.
// please try switching it to delegation ...
//aura.on.apply(player, arguments); // delegation.
//aura.on.call(player, type, handler); // delegation.
console.log("player.on :: player.getName() ", player.getName());
};
// ...
},
Constructor = function Player (name) {
// ...
// ...
this.getName = function() {
return name;
};
//this.addAura = function (aura) {
// addAura(this, aura)
//};
},
createPlayer = function (config) { // factory.
var
// ...
//player = (new Constructor)
player = (new Constructor(config.name))
// ...
;
//player.name = config.name;
player.addAura = function (aura) {
addAura(player, aura)
};
return player;
}
;
return {
create: createPlayer
};
}());
...
var // simplified aura object - for demonstration only.
aura = {
on: function (type, handler) {
if (typeof handler == "function") {
handler.call(this);
}
console.log("aura :: on - [this, arguments] ", this, arguments);
}
},
p1 = Player.create({name:"p1"}), // 1st character/player.
p2 = Player.create({name:"p2"}) // 2nd character/player.
;
...
p1.addAura(aura);
p2.addAura(aura);
p1.on("tick", function() {console.log("tick :: this", this);});
p2.on("remove", function() {console.log("remove :: this", this);});
Per tutto quanto sopra, personalmente preferisco sempre la funzione basata sull'approccio alla composizione mix .
La cosa che salta fuori per me è che, a meno che non ho letto male, gli eventi sono in corso abilitato su e applicato alla classe Player piuttosto che l'oggetto in sé Aura.
Se si segue il metodo di fare unicamente con lettore/personaggio casi, mentre qualsiasi altra cosa che può essere visto come insieme di ulteriori comportamenti che un giocatore può acquisire o può sbarazzarsi di (o che può essere assegnato a o può essere ritirato da qualsiasi giocatore) in fase di esecuzione, quindi per quest'ultimo, si parla di composizione basata sui ruoli. Quindi sia Observable
e Aura
sono mixin.
Non ci sarà nulla come un oggetto aura.
Se un giocatore non è già dispongono di comportamento osservabile, ma un comportamento aura fa affidamento su di essa, quindi il mixin Aura
dovrebbe fare uso del primo. La factory di un giocatore quindi non ha a che fare con Observable
ma un oggetto giocatore conterrà il comportamento Observable
non appena viene applicato un mixin Aura
.
... e ora tornare di nuovo a ...
io non sono certo come vorrei implementare questo modello per creare l'aura variabili.
Attaccandosi ai mixin basati su funzioni ci sono ancora principalmente due soluzioni. In primo luogo, come nell'esempio che ho fornito nella mia prima risposta, si può andare a un Mixin unico ma configurabile. Oppure, in secondo luogo, si preferisce il già menzionato molti frammenti di mix di aura.
var $rpg = { // mocking and faking heavily.
Event: {
enable: function (observable) {
observable.on = function (type, handler) {
if (typeof handler == "function") {
handler.call(this);
}
console.log("aura :: on - [this, arguments] ", this, arguments);
};
return observable;
}
}
};
...
var withAuraBase = function AuraBaseMixin (group) { // not a constructor but a simple function based "flight mixin".
var auraEnabled = this;
// ...
$rpg.Event.enable(auraEnabled);
// ...
auraEnabled.group = group;
// ...
};
var withFencinessFactorAura = function FencinessFactorAuraMixin (fencinessFactor) {
// ...
this.fencinessFactor = fencinessFactor;
// ...
};
var withCheatingFeaturesAura = function CheatingFeaturesAuraMixin (config) {
// ...
this.cheatingFeatures = config;
// ...
};
Il codice Player
fabbrica dall'alto poi si ridurrà a ...
var Player = (function() { // sort of factory module implementation.
var
// ...
// ...
Constructor = function Player (name) {
// ...
// ...
this.getName = function() {
return name;
};
},
createPlayer = function (config) { // factory.
var
// ...
player = (new Constructor(config.name))
// ...
;
//player.name = config.name;
return player;
}
;
return {
create: createPlayer
};
}());
...
var
p1 = Player.create({name:"player1"}), // 1st character/player.
p2 = Player.create({name:"player2"}) // 2nd character/player.
;
// applying mixin examples differently.
withAuraBase.call(p1, "classification");
withAuraBase.call(p2, "classification");
withFencinessFactorAura.call(p1, 10);
withCheatingFeaturesAura.call(p2, {/*cheatingFeaturesConfig*/});
console.log("p1.getName(), p1", p1.getName(), p1);
console.log("p2.getName(), p2", p2.getName(), p2);
p1.on("tick", function() {console.log("tick :: this", this);});
p2.on("remove", function() {console.log("remove :: this", this);});
Suggerimento: " meta "anche i mixin possono essere facilmente considerati guidato da quelli più piccoli. Abilitando così le composizioni di insiemi comportamentali su misura.
var withFencyAura = function FencyAurMixin (group, fencinessFactor) {
var auraEnabled = this;
withAuraBase.call(auraEnabled, group);
withFencinessFactorAura.call(auraEnabled, fencinessFactor);
};
var withCheatingAura = function CheatingAuraMixin (group, config) {
var auraEnabled = this;
withAuraBase.call(auraEnabled, group);
withCheatingFeaturesAura.call(auraEnabled, config);
};
Nota: In pratica Principalmente finire con mixins configurabili, mentre il sopra proposta esempio di composizione mixins da altri mixin sembra essere un caso raro.
Si può anche cambiare il mixin in modo che installi pigramente il membro '_events' sull'oggetto (quando viene chiamato' on' per esempio). Questo è l'approccio adottato da [asEvented] (https://github.com/mkuklis/asEvented/blob/master/asevented.js). – plalx
Che dire di un approccio compositivo ai mixin? 'Aura = eventMixin.mixInto (Aura);' dove questo applica il mixin e restituisce un nuovo costruttore composto. L'unica cosa è che l'applicazione di mixin non può essere differita poiché nessuno dovrebbe fare riferimento al vecchio costruttore a questo punto. – plalx
Grazie per i vostri commenti. Ho pensato di istanziare _eventi come hai descritto, non sono abbastanza sicuro di cosa mi abbia allontanato da quell'idea, quindi potrebbe essere quello che uso alla fine. Potresti elaborare ciò che intendi per "compositivo"? – Traverse