Esiste un motivo di design Decorator che si escludono a vicenda?

4

Conosciamo il modello di design Decorator , ma come si comporterebbe l'implementazione di l'esclusione reciproca decoratori?

Diciamo che ho uno schema decoratore per implementare i modificatori di armi in un gioco. I decoratori sarebbero, ad esempio, "velenosi", "incantati dal fuoco", "incantati dal ghiaccio", ecc. Ora diciamo che non voglio che la mia arma sia incendiata e incantata dal ghiaccio (solo perché), come andrei a implementare quella logica nel mio schema decoratore?

Avrei bisogno di scomporlo o di sovvertirlo oltre il riconoscimento?

La mia migliore idea ora è di avere un metodo GetDecorations() sulla mia interfaccia e usarlo nella nuova classe decoratore per garantire che la nuova decorazione non violi alcuna restrizione. Ma questo sembra andare contro il principio Decoratore di "non sapere" che puoi essere decorato ...

    
posta dstj 25.02.2016 - 17:28
fonte

1 risposta

4

Un decoratore in genere "avvolge" una classe e aggiunge comportamenti in determinati luoghi.

Se il tuo esempio, forse c'è un metodo che esegue un calcolo per ottenere il danno che un'arma infligge. Questo sarebbe più di un numero, restituendo anche un tipo, forse multiplo: 10 danni fisici, 2 danni da freddo.

Avrei un'interfaccia per un'arma, che è implementata da vere armi e dai tuoi decoratori. Avrei quindi due sotto-interfacce per le armi reali e per i decoratori: un decoratore non può decorare un altro decoratore perché il suo costruttore non accetterà quel tipo. In pseudocode:

class Damage {
  // state is multiple pairs of damage amounts and damage types.
}

interface Weapon {
  Damage getDamage();
}

interface RealWeapon : Weapon {}

interface WeaponDecorator : Weapon {}

class ColdEnchantment : WeaponDecorator {
  ColdEnchantment(RealWeapon w) { ... }
}

Puoi fare affidamento sul sistema di tipo statico nella tua lingua per impedire più decoratori in fase di compilazione.

Un altro metodo prevede che l'incantesimo sia un campo dell'arma:

interface Enchantment {
  // these are currently your decorators
}

interface Weapon [
  Damage getDamage();
  void setEnchantment(Enchantment e);
  void removeEnchantment();
}

Entrambi i metodi sono appropriati per diversi design: suggerisco di considerarli entrambi nel quadro generale del tuo programma e decidere quale sia un approccio più pulito.

    
risposta data 25.02.2016 - 17:45
fonte

Leggi altre domande sui tag