Strategia

W projektowaniu oprogramowania często spotykamy się z sytuacjami, w których różne części systemu wymagają różnych algorytmów. W takich przypadkach istotne jest, aby umożliwić elastyczne przełączanie pomiędzy różnymi strategiami bez konieczności modyfikacji istniejącego kodu. Wzorzec Strategia pozwala na odseparowanie algorytmów od reszty programu, co ułatwia zarządzanie nimi i wspiera zasadę otwarte/zamknięte (Open/Closed Principle) z SOLID.

Rys. 1 Diagram UML klas wzorca strategy

Wzorzec Strategia opiera się na definiowaniu rodziny algorytmów, umożliwiając obiektowi wybór jednego z nich w trakcie działania programu. Kluczowym elementem tego wzorca są trzy główne składniki:

  • Kontekst (Context): Jest to klasa, która posiada referencję do jednego z obiektów strategii oraz udostępnia interfejs dla klientów do korzystania z wybranego algorytmu.
  • Strategia (Strategy): Jest to interfejs lub abstrakcyjna klasa, która definiuje wspólny interfejs dla wszystkich konkret-nych algorytmów.
  • Konkretne Strategie (Concrete Strategies): Są to klasy implementujące interfejs strategii, reprezentujące konkretne algorytmy.

W tym przykładzie, PaymentContext to kontekst, który posiada referencję do interfejsu PaymentStrategy. Klient, korzystając z PaymentContext, może łatwo przełączać pomiędzy różnymi strategiami płatności, co umożliwia elastyczne zarządzanie procesem płatności.

// Interfejs Strategii
interface PaymentStrategy {
    void pay(int amount);
}

// Konkretne Strategie
class CreditCardPayment implements PaymentStrategy {
    @Override
    public void pay(int amount) {
        System.out.println("Paying " + amount + " using credit card.");
        // Logika płatności kartą kredytową
    }
}

class BankTransferPayment implements PaymentStrategy {
    @Override
    public void pay(int amount) {
        System.out.println("Making a bank transfer of " + amount + ".");
        // Logika przelewu bankowego
    }
}

class CashPayment implements PaymentStrategy {
    @Override
    public void pay(int amount) {
        System.out.println("Paying " + amount + " in cash.");
        // Logika płatności gotówką
    }
}

// Kontekst
class PaymentContext {
    private PaymentStrategy paymentStrategy;

    public PaymentContext(PaymentStrategy paymentStrategy) {
        this.paymentStrategy = paymentStrategy;
    }

    public void setPaymentStrategy(PaymentStrategy paymentStrategy) {
        this.paymentStrategy = paymentStrategy;
    }

    public void processPayment(int amount) {
        this.paymentStrategy.pay(amount);
    }
}

// Klient
public class Client {
    public static void main(String[] args) {
        // Utworzenie kontekstu płatności z domyślną strategią
        PaymentContext paymentContext = new PaymentContext(new CreditCardPayment());

        // Realizacja płatności różnymi strategiami
        paymentContext.processPayment(100);
        // Zmiana strategii płatności
        paymentContext.setPaymentStrategy(new BankTransferPayment());
        paymentContext.processPayment(200);
        paymentContext.setPaymentStrategy(new CashPayment());
        paymentContext.processPayment(50);
    }
}

Leave a Comment

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *