ホームページ  >  記事  >  Java  >  Javaデザインパターンの戦略パターンとは何ですか?

Javaデザインパターンの戦略パターンとは何ですか?

WBOY
WBOY転載
2023-04-29 11:43:061200ブラウズ

    戦略パターン

    別名: 戦略

    インテント

    戦略パターン a 一連のアルゴリズムを定義し、各アルゴリズムを別個のクラスに配置して、アルゴリズム オブジェクトを交換できるようにする動作設計パターン。

    Javaデザインパターンの戦略パターンとは何ですか?

    質問

    あなたはある日、観光客向けのツアー ガイド プログラムを作成する予定です。プログラムの中核機能は、ユーザーがどの都市でもすぐに位置を特定できるようにする美しい地図を提供することです。

    ユーザーが楽しみにしているアプリの新機能は、自動ルート計画です。住所を入力して、目的地までの最速ルートを地図上で確認したいと考えています。

    プログラムの最初のバージョンでは、道路ルートのみを計画できます。車で旅行する人はとても満足しています。しかし明らかに、誰もが休暇中に車を運転するわけではありません。次回のアップデートでは、ウォーキング ルートを計画する機能を追加しました。その後、公共交通機関のルートを計画する機能を追加しました。

    そして、これはほんの始まりにすぎません。すぐに、サイクリスト向けのルートを計画することになります。しばらくしたら、市内のすべての観光スポットを訪れるためのルートを再度計画する必要があります。

    Javaデザインパターンの戦略パターンとは何ですか?

    ガイド コードは非常に肥大化します。

    このアプリケーションはビジネスの観点からは非常に成功していますが、その技術的な部分が多くの悩みの種になる可能性があります。新しいルート計画アルゴリズムが追加されるたびに、ツアー ガイドのメイン クラスのサイズが大きくなり、アプリケーションが1倍に増加します。最終的に、ある時点で、このコードの山を維持できなくなったと感じるようになります。

    単純な欠陥を修正する場合でも、ストリート ウェイトを微調整する場合でも、アルゴリズムに変更を加えるとクラス全体に影響があり、すでに機能しているコードにバグが混入するリスクが高まります。

    さらに、チームワークも非効率になります。アプリが正常にリリースされた後にチーム メンバーを募集すると、マージ競合の作業に時間がかかりすぎると不満が出るでしょう。新しい機能を実装するプロセスでは、チームは同じ巨大なクラスを変更する必要があるため、チームが作成するコードが互いに競合する可能性があります。

    ソリューション

    Strategy パターンは、さまざまな方法で特定のタスクを達成する役割を担うクラスを特定し、その中のアルゴリズムを戦略と呼ばれる一連の独立したクラスに抽出することを提案します。

    context という名前の元のクラスには、各戦略への参照を格納するメンバー変数が含まれている必要があります。コンテキストはタスクを実行しませんが、接続されたポリシー オブジェクトに作業を委任します。

    コンテキストは、タスクのニーズを満たすアルゴリズムを選択する責任を負いません。クライアントは、必要な戦略をコンテキストに渡します。実際、コンテキストは戦略についてあまり知りません。同じ共通インターフェイスを介してすべての戦略と対話します。必要なのは、選択された戦略にカプセル化されたアルゴリズムをトリガーするメソッドを公開することだけです。

    したがって、コンテキストは特定のポリシーから独立させることができます。これにより、コンテキスト コードやその他の戦略を変更せずに、新しいアルゴリズムを追加したり、既存のアルゴリズムを変更したりすることができます。

    Javaデザインパターンの戦略パターンとは何ですか?

    #ルート計画戦略。

    ツアー ガイド アプリケーションでは、各ルート計画アルゴリズムを 1 つの

    build­Route生成ルート メソッドのみを使用して独立したクラスに抽出できます。このメソッドは、開始点と終了点をパラメータとして受け取り、ルート中間点のコレクションを返します。

    各ルート計画クラスに渡されるパラメータがまったく同じであっても、作成されるルートはまったく異なる場合があります。メイン ツアー ガイド クラスの主な仕事は、地図上に一連の中間点をレンダリングすることであり、アルゴリズムがどのように選択されるかは気にしません。このクラスには、現在のパス計画戦略を切り替えるためのメソッドもあるため、クライアント (ユーザー インターフェイスのボタンなど) は、現在選択されているパス計画動作を別の戦略に置き換えることができます。

    現実世界の例え

    Javaデザインパターンの戦略パターンとは何ですか?

    空港までのさまざまな旅行戦略

    空港に行く必要がある場合。バス、タクシー、自転車のいずれかを選択できます。これらはあなたの旅行戦略です。予算や時間などの要素に基づいて、これらの戦略のいずれかを選択できます。

    戦略パターン構造

    Javaデザインパターンの戦略パターンとは何ですか?

    • 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 サイトの他の関連記事を参照してください。

    声明:
    この記事はyisu.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。