ストラテジーパターン
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する新しいクラスを作成するだけです。既存のコードを変更する必要はありません。
チャレンジ
簡単Strategy Pattern を使用してテキスト formatting システムを構築しましょう!実行時に異なる formatting strategies を入れ替えて、さまざまな方法でテキストを変換できるシステムを作成します。複数の出力形式をサポートする必要があるアプリケーションに最適です。
コードを4つのファイルに整理します。
TextFormatter.java:すべての formatting strategies が implement するTextFormatterinterface を Define します。文字列を受け取り、formatted version を返す単一のメソッドString format(String text)を declare する必要があります。Formatters.java:TextFormatterinterface を implement する3つの concrete strategies を Create します。UpperCaseFormatter- テキストをすべて大文字に変換します。LowerCaseFormatter- テキストをすべて小文字に変換します。TitleCaseFormatter- each word の first letter を大文字にし、rest を小文字にします。単語はスペースで区切られます。TextEditor.java:formatting strategy を使用する context class を Create します。TextEditorには次の要素が必要です。current
TextFormatterstrategy を 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 world と title の場合、output は次のようになります。
Published: hello world
Published: Hello WorldTextEditor が具体的な 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 を呼び出す
}
}このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
4継承
継承の基本 (extends)super キーワードメソッドのオーバーライド (@Override)コンストラクタチェーンObject クラス単一継承と多段階継承なぜ多重継承ができないのかまとめ:従業員の階層構造自分で練習してみよう: Javaオンラインコンパイラ