Menu
Coddy logo textTech

Wzorzec Strategy

Część sekcji Programowanie obiektowe ścieżki Java w Coddy. Lekcja 69 z 87.

Wzorzec strategii to behawioralny wzorzec projektowy, który pozwala zdefiniować rodzinę algorytmów, zamknąć każdy z nich we własnej klasie i sprawić, by można je było wzajemnie zastępować. Zamiast zakodowywać na stałe określone zachowanie, możesz w czasie działania programu zamieniać algorytmy bez zmieniania kodu, który z nich korzysta.

Wyobraź sobie system płatności obsługujący wiele metod płatności. Bez wzorca Strategia skończyłoby się na nieuporządkowanej logice warunkowej. Dzięki niemu każda metoda płatności staje się własną strategią:

interface PaymentStrategy {
    void pay(int amount);
}

class CreditCardPayment implements PaymentStrategy {
    public void pay(int amount) {
        System.out.println("Paid " + amount + " via Credit Card");
    }
}

class PayPalPayment implements PaymentStrategy {
    public void pay(int amount) {
        System.out.println("Paid " + amount + " via PayPal");
    }
}

Klasa kontekstu przechowuje odwołanie do strategii i deleguje jej wykonanie. Kluczowe jest to, że kontekst nie wie, której konkretnej strategii używa. Zna jedynie interfejs:

class ShoppingCart {
    private PaymentStrategy paymentStrategy;
    
    public void setPaymentStrategy(PaymentStrategy strategy) {
        this.paymentStrategy = strategy;
    }
    
    public void checkout(int amount) {
        paymentStrategy.pay(amount);
    }
}

Teraz możesz dynamicznie zmieniać sposób płatności:

ShoppingCart cart = new ShoppingCart();

cart.setPaymentStrategy(new CreditCardPayment());
cart.checkout(100);  // Zapłacono 100 kartą kredytową

cart.setPaymentStrategy(new PayPalPayment());
cart.checkout(50);   // Zapłacono 50 przez PayPal

Wzorzec Strategii sprawdza się, gdy masz wiele sposobów wykonania działania i chcesz łatwo się między nimi przełączać. Dodanie nowej metody płatności oznacza po prostu utworzenie nowej klasy implementującej PaymentStrategy: nie trzeba wprowadzać żadnych zmian w istniejącym kodzie.

challenge icon

Wyzwanie

Łatwy

Zbudujmy system formatowania tekstu z wykorzystaniem wzorca Strategia! Utworzysz system, w którym różne strategie formatowania można wymieniać w czasie działania programu, aby przekształcać tekst na różne sposoby — idealne rozwiązanie dla aplikacji, która musi obsługiwać wiele formatów wyjściowych.

Rozmieścisz kod w czterech plikach:

  • TextFormatter.java: Zdefiniuj interfejs TextFormatter, który będą implementować wszystkie strategie formatowania. Powinien deklarować jedną metodę String format(String text), która przyjmuje ciąg znaków i zwraca jego sformatowaną wersję.
  • Formatters.java: Utwórz trzy konkretne strategie implementujące interfejs TextFormatter:

    UpperCaseFormatter — przekształca tekst, zamieniając wszystkie litery na wielkie.

    LowerCaseFormatter — przekształca tekst, zamieniając wszystkie litery na małe.

    TitleCaseFormatter — zamienia pierwszą literę każdego słowa na wielką, a pozostałe na małe. Słowa są oddzielone spacjami.

  • TextEditor.java: Utwórz klasę kontekstu korzystającą ze strategii formatowania. Klasa TextEditor powinna mieć:

    Prywatne pole przechowujące bieżącą strategię TextFormatter.

    Metodę setFormatter(TextFormatter formatter), która zmienia aktywną strategię formatowania.

    Metodę publishText(String text), która stosuje bieżący formater do tekstu i wyświetla Published: [formatted text]. Jeśli nie ustawiono żadnego formatera, powinna wyświetlić niezmieniony tekst Published: [original text].

  • Main.java: Połącz elementy systemu strategii! Otrzymasz dwa dane wejściowe: tekst do sformatowania (String) i styl formatowania (String: "upper", "lower" lub "title").

    Utwórz obiekt TextEditor i najpierw wywołaj publishText z tekstem wejściowym, zanim ustawisz jakikolwiek formater (demonstrując domyślne działanie).

    Następnie, w zależności od podanego stylu, ustaw odpowiednią strategię formatowania i ponownie wywołaj publishText z tym samym tekstem, aby wyświetlić sformatowany wynik.

Otrzymasz po kolei dwa dane wejściowe: tekst do sformatowania (String) i styl formatowania (String).

Na przykład dla danych wejściowych hello world i title wynik będzie następujący:

Published: hello world
Published: Hello World

Zauważ, że TextEditor nie wie nic o szczegółach logiki formatowania. Po prostu przekazuje zadanie aktualnie ustawionej strategii. Dzięki temu dodawanie nowych stylów formatowania bez modyfikowania kodu edytora jest niezwykle proste!

Spróbuj swoich sił

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String text = scanner.nextLine();
        String style = scanner.nextLine();
        
        // TODO: Utwórz instancję TextEditor
        
        // TODO: Wywołaj publishText z tekstem wejściowym (przed ustawieniem formatowania)
        
        // TODO: Na podstawie podanego stylu ("upper", "lower" lub "title"),
        // ustaw odpowiednie formatowanie i ponownie wywołaj publishText
        
    }
}
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Programowanie obiektowe

Poćwicz samodzielnie: Kompilator Java online