La tua domanda è un po 'oscura, ma ti spiegherò qual è il modello di strategia nel caso in cui non hai una buona comprensione.
Strategia consente di scambiare parte della funzionalità di un oggetto in modo dinamico durante il runtime. Questo viene fatto incapsulando le diverse funzionalità in classi che condividono tutti un supertipo tipico, e avendo l'oggetto in questione (il "contesto") possedere un riferimento di questo supertipo.
Di quando, l'oggetto vuole eseguire alcune funzionalità, in realtà delega l'oggetto Strategia di sua proprietà. Possiamo scambiare l'oggetto Strategia corrente con uno diverso dinamicamente, ad es. un metodo di setter pubblico.
Così scambiando la funzionalità di proprietà dell'oggetto.
Si noti che il pattern Strategy è chiamato così perché consente di scegliere diverse "strategie" per eseguire generalmente la stessa operazione.
Ad esempio, in un gioco potresti avere una classe Soldier. Gli oggetti di questa classe sono in grado di attaccare i cattivi tramite il loro metodo attack()
.
Ma cosa succederebbe se volessimo attack()
a fare qualcosa di diverso in base all'arma attuale detenuta dal soldato? Per esempio se attualmente l'arma è una pistola, attack()
sparerà ai proiettili. Se è un coltello, attack()
farà sì che il soldato pugni le persone.
Un modo ingenuo per avvicinarsi a questo, sarebbe per Soldier
per contenere una variabile String
che indica quale sia l'arma corrente. attack()
avrà una lunga catena else if
per determinare la logica corretta in base all'attuale arma. Qualcosa del genere:
class Soldier{
String weapon;
void setWeapon(String w){ weapon = w; }
void attack(){
if(weapon.equals("gun")) // shoot bullets
else if(weapon.equals("knife")) // slash people
// else if ...
}
}
Ma questo approccio è cattivo e sicuramente non molto orientato agli oggetti. Cosa c'è di male in questo?
Supponiamo che tu abbia già 5 diversi tipi di armi e che ne vuoi aggiungere un'altra al gioco. Dovresti andare in Soldato e aggiungere un altro else if
per abbinare.
Non è così male, ma cosa succede se più classi nel tuo gioco hanno bisogno di usare le armi? Ad esempio, una DefenseTurret potrebbe anche contenere un tipo specifico di arma che governerebbe il modo in cui attack()
s.
Ciò significherebbe un sacco di duplicazione del codice tra Soldier e DefenseTurret. E ancora, se vuoi aggiungere una nuova arma - devi andare a entrambe queste classi e aggiungere la logica a loro, con conseguente classi che continuano a crescere e sempre più duplicazioni di codice. Probabilmente si traducono in bug sgradevoli.
Il modello di strategia è esattamente in grado di fornire una soluzione OO più elegante a queste situazioni.
Con la Strategia, ogni tipo di arma sarà implementata nella propria sottoclasse di armi. L'arma sarebbe una classe astratta (o un'interfaccia) che definisce un metodo attack()
astratto. Ognuna delle sottoclassi implementa questo metodo in modo diverso.
Il soldato, invece di detenere un membro String weapon
, avrà un membro Weapon weapon
. Ed è il metodo attack()
, invece di contenere una lunga catena else if
, semplicemente delegherà all'arma: weapon.attack()
. Codice per chiarire:
class Soldier{
// .. stuff omitted
Weapon weapon;
void attack(){
weapon.attack();
}
void setWeapon(Weapon newWeapon){
weapon = newWeapon;
}
}
abstract class Weapon{
public abstract void attack();
}
class Gun extends Weapon{
public void attack{ /* shoot some bullets */ }
}
class Knife extends Weapon{
public void attack{ /* stab some bad guys */ }
}
Molto più elegante.
Ecco un diagramma UML per chiarire ancora di più:
E ora, e se volessi dare a DefenseTurret
alcune capacità di sparare con la pistola? Dagli solo un riferimento Weapon
e assegnagli un delegato, come hai fatto con Soldier. Puoi riutilizzare il codice che hai già scritto senza copiarlo sempre.
Spero che questo chiarisca cos'è la Strategia. Per quanto riguarda la tua domanda, non riuscivo davvero a capirlo, ma mi sembra che quello che stai facendo non chiarisca come un'implementazione della strategia dal momento dello scambio dei dati (cioè con un semplice setter che imposta un valore String), ma non lo scambio funzionalità e logica.
Sarò felice di aiutarti se spiegherai in modo più chiaro qual è il tuo problema.