別名: 戦略
戦略パターン a 一連のアルゴリズムを定義し、各アルゴリズムを別個のクラスに配置して、アルゴリズム オブジェクトを交換できるようにする動作設計パターン。
あなたはある日、観光客向けのツアー ガイド プログラムを作成する予定です。プログラムの中核機能は、ユーザーがどの都市でもすぐに位置を特定できるようにする美しい地図を提供することです。
ユーザーが楽しみにしているアプリの新機能は、自動ルート計画です。住所を入力して、目的地までの最速ルートを地図上で確認したいと考えています。
プログラムの最初のバージョンでは、道路ルートのみを計画できます。車で旅行する人はとても満足しています。しかし明らかに、誰もが休暇中に車を運転するわけではありません。次回のアップデートでは、ウォーキング ルートを計画する機能を追加しました。その後、公共交通機関のルートを計画する機能を追加しました。
そして、これはほんの始まりにすぎません。すぐに、サイクリスト向けのルートを計画することになります。しばらくしたら、市内のすべての観光スポットを訪れるためのルートを再度計画する必要があります。
ガイド コードは非常に肥大化します。
このアプリケーションはビジネスの観点からは非常に成功していますが、その技術的な部分が多くの悩みの種になる可能性があります。新しいルート計画アルゴリズムが追加されるたびに、ツアー ガイドのメイン クラスのサイズが大きくなり、アプリケーションが1倍に増加します。最終的に、ある時点で、このコードの山を維持できなくなったと感じるようになります。
単純な欠陥を修正する場合でも、ストリート ウェイトを微調整する場合でも、アルゴリズムに変更を加えるとクラス全体に影響があり、すでに機能しているコードにバグが混入するリスクが高まります。
さらに、チームワークも非効率になります。アプリが正常にリリースされた後にチーム メンバーを募集すると、マージ競合の作業に時間がかかりすぎると不満が出るでしょう。新しい機能を実装するプロセスでは、チームは同じ巨大なクラスを変更する必要があるため、チームが作成するコードが互いに競合する可能性があります。
Strategy パターンは、さまざまな方法で特定のタスクを達成する役割を担うクラスを特定し、その中のアルゴリズムを戦略と呼ばれる一連の独立したクラスに抽出することを提案します。
context という名前の元のクラスには、各戦略への参照を格納するメンバー変数が含まれている必要があります。コンテキストはタスクを実行しませんが、接続されたポリシー オブジェクトに作業を委任します。
コンテキストは、タスクのニーズを満たすアルゴリズムを選択する責任を負いません。クライアントは、必要な戦略をコンテキストに渡します。実際、コンテキストは戦略についてあまり知りません。同じ共通インターフェイスを介してすべての戦略と対話します。必要なのは、選択された戦略にカプセル化されたアルゴリズムをトリガーするメソッドを公開することだけです。
したがって、コンテキストは特定のポリシーから独立させることができます。これにより、コンテキスト コードやその他の戦略を変更せずに、新しいアルゴリズムを追加したり、既存のアルゴリズムを変更したりすることができます。
#ルート計画戦略。 ツアー ガイド アプリケーションでは、各ルート計画アルゴリズムを 1 つのbuildRoute生成ルート メソッドのみを使用して独立したクラスに抽出できます。このメソッドは、開始点と終了点をパラメータとして受け取り、ルート中間点のコレクションを返します。
Context (コンテキスト) は、特定の戦略への参照を維持し、渡された ポリシー インターフェイスはこのオブジェクトと通信します。
Strategy (Strategy) インターフェイスは、すべての特定の戦略に共通のインターフェイスであり、戦略を実行するためのコンテキスト メソッドを宣言します。
具体的な戦略 (具体的な戦略) は、コンテキストによって使用されるアルゴリズムのさまざまなバリエーションを実装します。
コンテキストはアルゴリズムを実行する必要がある場合、接続されているポリシー オブジェクトの実行メソッドを呼び出します。関係する戦略の種類とアルゴリズムの実行方法については、文脈が不明瞭です。
クライアント (クライアント) は、特定のポリシー オブジェクトを作成し、それをコンテキストに渡します。コンテキストは、クライアントが実行時に関連ポリシーをオーバーライドできるようにセッターを提供します。
この例では、コンテキストは複数の 戦略を使用してさまざまな計算操作を実行します。
// 策略接口声明了某个算法各个不同版本间所共有的操作。上下文会使用该接口来 // 调用有具体策略定义的算法。 interface Strategy is method execute(a, b) // 具体策略会在遵循策略基础接口的情况下实现算法。该接口实现了它们在上下文 // 中的互换性。 class ConcreteStrategyAdd implements Strategy is method execute(a, b) is return a + b class ConcreteStrategySubtract implements Strategy is method execute(a, b) is return a - b class ConcreteStrategyMultiply implements Strategy is method execute(a, b) is return a * b // 上下文定义了客户端关注的接口。 class Context is // 上下文会维护指向某个策略对象的引用。上下文不知晓策略的具体类。上下 // 文必须通过策略接口来与所有策略进行交互。 private strategy: Strategy // 上下文通常会通过构造函数来接收策略对象,同时还提供设置器以便在运行 // 时切换策略。 method setStrategy(Strategy strategy) is this.strategy = strategy // 上下文会将一些工作委派给策略对象,而不是自行实现不同版本的算法。 method executeStrategy(int a, int b) is return strategy.execute(a, b) // 客户端代码会选择具体策略并将其传递给上下文。客户端必须知晓策略之间的差 // 异,才能做出正确的选择。 class ExampleApplication is method main() is 创建上下文对象。 读取第一个数。 读取最后一个数。 从用户输入中读取期望进行的行为。 if (action == addition) then context.setStrategy(new ConcreteStrategyAdd()) if (action == subtraction) then context.setStrategy(new ConcreteStrategySubtract()) if (action == multiplication) then context.setStrategy(new ConcreteStrategyMultiply()) result = context.executeStrategy(First number, Second number) 打印结果。
オブジェクト内でさまざまなアルゴリズム バリアントを使用し、実行時にアルゴリズムを切り替えられるようにしたい場合は、ストラテジー モードを使用できます。
Strategy パターンを使用すると、特定のサブタスクをさまざまな方法で実行できるさまざまなサブオブジェクトにオブジェクトを関連付けることによって、実行時にオブジェクトの動作を間接的に変更できます。
特定の動作の実行方法がわずかに異なるだけの類似したクラスが多数ある場合は、Strategy パターンを使用します。
Strategy パターンを使用すると、さまざまな動作を別のクラス階層に抽出し、元のクラスを同じクラスに結合できるため、重複するコードを減らすことができます。
アルゴリズムがコンテキストのロジックにおいて特に重要ではない場合、このパターンを使用すると、クラスのビジネス ロジックをそのアルゴリズム実装の詳細から分離できます。
Strategy パターンを使用すると、コード、内部データ、およびさまざまなアルゴリズムの依存関係を他のコードから分離できます。さまざまなクライアントがシンプルなインターフェイスを通じてアルゴリズムを実行でき、実行時に切り替えることができます。
このパターンは、クラス内で複雑な条件演算子を使用して、同じアルゴリズムの異なるバリアント間を切り替える場合に使用できます。
Strategy パターンは、同じインターフェイスから継承されたすべてのアルゴリズムを独立したクラスに抽出するため、条件ステートメントは必要なくなります。プリミティブ オブジェクトは、アルゴリズムのすべてのバリアントを実装するのではなく、個々のアルゴリズム オブジェクトの 1 つに実行を委任します。
コンテキスト クラスから変更頻度が高いアルゴリズムを見つけます (実行時演算子でアルゴリズムのバリアントを選択するために使用される複雑な条件である場合もあります) 。
このアルゴリズムのすべてのバリアントに共通の戦略インターフェイスを宣言します。
アルゴリズムをそれぞれのクラスに 1 つずつ抽出し、それらはすべて戦略インターフェイスを実装する必要があります。
コンテキスト クラスにメンバー変数を追加して、ポリシー オブジェクトへの参照を保存します。次に、メンバー変数を変更するためのセッターを提供します。コンテキストは、ポリシー インターフェイスを介してのみポリシー オブジェクトと対話できます。必要に応じて、ポリシーがそのデータにアクセスできるようにインターフェイスを定義できます。
コンテキストが期待どおりにメイン ジョブを完了できるように、クライアントはコンテキスト クラスを対応するポリシーに関連付ける必要があります。
実行時にオブジェクト内のアルゴリズムを切り替えることができます。
アルゴリズムの実装を、アルゴリズムを使用するコードから分離できます。
テンプレート メソッド パターンは継承メカニズムに基づいています。これにより、サブクラスのコンテンツの一部を拡張することでアルゴリズムの一部を変更できます。ストラテジは合成メカニズムに基づいています。対応する動作にさまざまなストラテジを提供することで、オブジェクトの動作の一部を変更できます。テンプレート メソッドはクラス レベルで動作するため、静的です。ポリシーはオブジェクト レベルで動作するため、実行時に動作を切り替えることができます。
国家は戦略の延長として考えることができます。どちらも合成メカニズムに基づいており、作業の一部を「ヘルパー」オブジェクトに委任することで、さまざまな状況で動作を変更します。このポリシーにより、これらのオブジェクトは互いに完全に独立し、他のオブジェクトの存在は認識されません。ただし、状態パターンは特定の状態間の依存関係を制限せず、さまざまなシナリオで状態を変更できるようにします。
以上がJavaデザインパターンの戦略パターンとは何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。