- natalia.kaczynska.programista@gmail.com
Strategy (Strategia)
Wyobraźmy sobie grę komputerową, w której postać może poruszać się na trzy różne sposoby: chodząc, pływając i latając. Każdy z tych sposobów wymaga innej logiki i zachowania w grze.
Najprostszym podejściem byłoby napisanie jednej klasy, która obsługuje wszystkie możliwe rodzaje ruchu za pomocą instrukcji warunkowych (if lub switch). Takie rozwiązanie działa, ale ma swoje wady – każda zmiana sposobu poruszania wymaga modyfikacji klasy, a kod szybko staje się trudny do utrzymania.
Poniżej przedstawiam przykład kodu bez użycia wzorca projektowego Strategia, aby pokazać typowe problemy tego podejścia.
Tutaj mamy klasę Character:
package motion;
public class Character {
private String moveType;
public Character(String moveType) {
this.moveType = moveType;
}
public void makeAMove() {
switch (moveType) {
case "walking":
System.out.println("Character walks on the ground.");
break;
case "flying":
System.out.println("Character flies in the air.");
break;
case "swimming":
System.out.println("Character swims in water.");
break;
default:
System.out.println("Unknown move type!");
}
}
public void setMoveType(String moveType) {
this.moveType = moveType;
}
}
Wywołanie w klasie głównej:
import motion.Character;
public class Demo {
public static void main(String[] args) {
Character character = new Character("walking");
character.makeAMove();
character.setMoveType("flying");
character.makeAMove();
character.setMoveType("swimming");
character.makeAMove();
}
}
W tej wersji gry pokazujemy, jak postać może poruszać się w różny sposób: chodzić, latać lub pływać. Zamiast używać wielu instrukcji warunkowych w jednej klasie, zastosuję wzorzec Strategia.
Strategia pozwala oddzielić różne sposoby poruszania się od samej postaci. Dzięki temu łatwo można:
dodać nowe rodzaje ruchu,
zmieniać ruch w trakcie gry,
utrzymać kod w czystości i przejrzystości.
Poniżej znajduje się przykład implementacji wzorca Strategia w Javie:
Na początek – w paczce strategy.move_strategy implementuję interfejs MoveBehavior, który definiuje odpoweidnie działanie:
package strategy.move_strategy;
public interface MoveBehavior {
public void move();
}
Następnie, implementuję klasy ruchu.
Klasa Walking:
package strategy.move_strategy;
public class Walking implements MoveBehavior{
public void move() {
System.out.println("Character walks on the ground.");
}
}
Klasa Flying:
package strategy.move_strategy;
public class Flying implements MoveBehavior{
public void move() {
System.out.println("Character flies in the air.");
}
}
Klasa Swimming:
package strategy.move_strategy;
public class Swimming implements MoveBehavior{
public void move() {
System.out.println("Character swims in the water.");
}
}
Klasa główna:
import context.Character;
import strategy.move_strategy.Flying;
import strategy.move_strategy.Swimming;
import strategy.move_strategy.Walking;
public class Demo {
public static void main(String[] args){
Character character = new Character();
character.setMoveBehavior(new Walking());
character.makeAMove();
character.setMoveBehavior(new Flying());
character.makeAMove();
character.setMoveBehavior(new Swimming());
character.makeAMove();
}
}