Menu
Coddy logo textTech

ストラテジーパターン

CoddyのJavaジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 69/87。

Strategyパターンは、アルゴリズムのファミリーを定義し、それぞれを独自のクラスにカプセル化して、互換可能にする行動に関するデザインパターンです。特定の動作をハードコーディングする代わりに、それを使用するコードを変更せず、実行時にアルゴリズムを入れ替えられます。

複数の支払い方法に対応する支払いシステムを想像してください。Strategy Patternがなければ、煩雑な条件分岐ロジックになってしまいます。Strategy Patternを使えば、それぞれの支払い方法が独自のstrategyになります。

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");
    }
}

contextクラスは戦略への参照を保持し、処理をその戦略に委譲します。重要なのは、contextがどの具体的な戦略を使用しているかを認識していない点です。認識しているのはinterfaceだけです。

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

これで、支払いの動作を動的に変更できます。

ShoppingCart cart = new ShoppingCart();

cart.setPaymentStrategy(new CreditCardPayment());
cart.checkout(100);  // クレジットカードで100を支払った

cart.setPaymentStrategy(new PayPalPayment());
cart.checkout(50);   // PayPalで50を支払った

Strategy Patternは、アクションを実行する方法が複数あり、それらを簡単に切り替えたい場合に力を発揮します。新しい支払い方法を追加するには、PaymentStrategyをimplementsする新しいクラスを作成するだけです。既存のコードを変更する必要はありません。

challenge icon

チャレンジ

簡単

Strategy Pattern を使用してテキスト formatting システムを構築しましょう!実行時に異なる formatting strategies を入れ替えて、さまざまな方法でテキストを変換できるシステムを作成します。複数の出力形式をサポートする必要があるアプリケーションに最適です。

コードを4つのファイルに整理します。

  • TextFormatter.java:すべての formatting strategies が implement する TextFormatter interface を Define します。文字列を受け取り、formatted version を返す単一のメソッド String format(String text) を declare する必要があります。
  • Formatters.javaTextFormatter interface を implement する3つの concrete strategies を Create します。

    UpperCaseFormatter - テキストをすべて大文字に変換します。

    LowerCaseFormatter - テキストをすべて小文字に変換します。

    TitleCaseFormatter - each word の first letter を大文字にし、rest を小文字にします。単語はスペースで区切られます。

  • TextEditor.java:formatting strategy を使用する context class を Create します。TextEditor には次の要素が必要です。

    current TextFormatter strategy を hold する private field。

    active formatting strategy を changes する setFormatter(TextFormatter formatter) メソッド。

    current formatter をテキストに適用し、Published: [formatted text] を出力する publishText(String text) メソッド。formatter が設定されていない場合は、変更せずに Published: [original text] を出力する必要があります。

  • Main.java:strategy system をまとめます!2つの input を受け取ります。format するテキスト(String)と formatting style(String:"upper""lower"、または "title")です。

    TextEditor を Create し、formatter を設定する前に、まず input text を使って publishText を call します(default behavior を示します)。

    次に、style input Based で appropriate formatter strategy を設定し、同じテキストを使って publishText をもう一度 call し、formatted result を表示します。

2つの input を順番に受け取ります。format するテキスト(String)と formatting style(String)です。

たとえば、input が hello worldtitle の場合、output は次のようになります。

Published: hello world
Published: Hello World

TextEditor が具体的な formatting logic について何も知らないことに注目してください。現在設定されている strategy に単純に委譲します。これにより、editor code に触れることなく新しい formatting styles を簡単に Add できます。

自分で試してみよう

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: TextEditor のインスタンスを作成する
        
        // TODO: 入力テキストで publishText を呼び出す(フォーマッターを設定する前に)
        
        // TODO: スタイル入力 ("upper", "lower", または "title") に基づいて、
        // 適切なフォーマッターを設定し、再度 publishText を呼び出す
        
    }
}
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

オブジェクト指向プログラミングのすべてのレッスン

自分で練習してみよう: Javaオンラインコンパイラ