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();
    }
}
Przewijanie do góry