実生活では、多くの場合、選択する特定の目標を達成するための様々な戦略の存在下で遭遇した、例えば、旅行者は飛行機、電車、自転車で旅行や自分の自家用車を開始することができ、スーパーマーケットでは、商品の配送をプロモーション割引の使用を排除すること統合や他の方法を送信します。
多くの場合、似たような状況に遭遇したソフトウェア開発では、特定の機能を実現する複数のアルゴリズムや戦略がある場合、我々はそのようなデータが戦略バブルを並べ替えて、環境条件やアルゴリズムや戦略に応じて、異なるオプションの機能を実行することができますソート、選択ソート、挿入ソート、バイナリ・ソート。
あなたは(ハードコードされていること)を達成するために、複数の条件分岐文を使用している場合は、条件文だけではなく、非常に複雑になり、追加、削除、または開閉の原則に反する維持しやすいソースコードを、修正するアルゴリズムを交換してください。パターンは、問題を解決するには良い戦略であることができます。
戦略パターンの定義と特性
定義された戦略(ストラテジー)モード:このモードでは、アルゴリズムのセットを定義し、各アルゴリズムをカプセル化し、彼らはお互いを置き換えることができますのでこと、およびアルゴリズムの変更は、アルゴリズムを使用している顧客には影響を与えません。オブジェクトの行動パターンに属する戦略パターンは、それは、アルゴリズムによって責任のアルゴリズムをカプセル化アルゴリズムの使用を分離し、これらのアルゴリズムを管理するためのさまざまなオブジェクトに割り当てられました。
戦略パターンの主な利点は次の通り。
- 複数の条件文は、維持し、複数の条件文の使用を避けるために、戦略パターンを使用することは容易ではありません。
- Strategyパターンの申し出再利用可能なアルゴリズムの家族の範囲は、一般的なコードの家族を継承することができ、アルゴリズムの適切な使用は、そのコードの回避重複するとして、親クラスに移しました。
- 戦略モードは同じ動作の異なる実装を提供することができ、顧客は、異なる時間または異なる容量の要件を選択することができます。
- 戦略モードは開閉の原則のための完全なサポートを提供し、それが元のコード、柔軟なアドオン新しいアルゴリズムを変更せずにすることができます。
- Strategyパターンは、環境クラスにアルゴリズムを使用して、クラスの特定の戦略にアルゴリズムの移行には、両者の分離を達成するために。
主な欠点は次の通り。
- クライアントは、タイムリーに適切なアルゴリズムのクラスを選択するために、すべてのポリシーアルゴリズムの違いを理解する必要があります。
- 戦略カテゴリの多くの原因戦略パターン。
構造と戦略パターンの実装
Strategyパターンは、アルゴリズムのセットを用意することであり、抽象クラスポリシーのサブクラスとしてポリシークラス一連のアルゴリズムへのパッケージのセット。戦略モードの焦点は、アルゴリズムを実装する方法はありませんが、これらのアルゴリズムを整理する方法、そのプログラムの構造をより柔軟こと、より良いメンテナンス性と拡張性を持ち、そして今、私たちは基本的な構造と実装を分析する必要があります。
1.構造モデル
戦略パターンの主な役割は次の通り。
- アブストラクト(戦略)カテゴリ:このインタフェースは、別のインターフェイスを使用して、環境の役割は、このアルゴリズムでは、一般的に使用されるインターフェイスや抽象クラスが実装を呼び出すさまざまな方法で種々の異なるアルゴリズムに共通のインタフェースを定義します。
- 具体的な戦略(コンクリート戦略)カテゴリ:定義されたインタフェースを達成するための抽象的な戦略は、特定のアルゴリズムを提供しています。
- 参照は、ポリシークラスを保持し、最終的にクライアントの呼び出しに:環境(コンテキスト)クラス。
図1に示す構造。
実現の2モード
Strategyパターンの実装コードは次のよう:
package strategy;
public class StrategyPattern
{
public static void main(String[] args)
{
Context c=new Context();
Strategy s=new ConcreteStrategyA();
c.setStrategy(s);
c.strategyMethod();
System.out.println("-----------------");
s=new ConcreteStrategyB();
c.setStrategy(s);
c.strategyMethod();
}
}
//抽象策略类
interface Strategy
{
public void strategyMethod(); //策略方法
}
//具体策略类A
class ConcreteStrategyA implements Strategy
{
public void strategyMethod()
{
System.out.println("具体策略A的策略方法被访问!");
}
}
//具体策略类B
class ConcreteStrategyB implements Strategy
{
public void strategyMethod()
{
System.out.println("具体策略B的策略方法被访问!");
}
}
//环境类
class Context
{
private Strategy strategy;
public Strategy getStrategy()
{
return strategy;
}
public void setStrategy(Strategy strategy)
{
this.strategy=strategy;
}
public void strategyMethod()
{
strategy.strategyMethod();
}
}
次のようにプログラムの結果は以下のとおりです。
具体策略A的策略方法被访问!
-----------------
具体策略B的策略方法被访问!
戦略パターンの適用例
調理中の[実施例1]アプリケーション戦略モード「ヘアリー」。
分析:カニの実践に関しては、多くのがありますが、我々はカニを蒸しカニは2つのメソッドを煮込み、例えば、戦略パターンの適用を説明しています。
まず、CookingMethod()を料理の方法の抽象含ま戦略(CrabCooking)を、処理カニの抽象的定義は、次に、蒸しカニ(SteamedCrabs)と蒸しカニ(BraisedCrabs)特定のポリシーのクラスを定義する実装する抽象を方法抽象クラスポリシー、よく表示される本手順の結果として、図、コンクリートサブクラスJLabelのにポリシークラス定義、台所(キッチン)環境クラスの最後に、定義、及び調理選択ポリシーのセットを有します方法、調理クラスキッチンを求めることにより、顧客クラスポリシーを、調理し、図の形で示した結果、図2は、図1の構成図です。
コードは以下の通りであります:
package strategy;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class CrabCookingStrategy implements ItemListener
{
private JFrame f;
private JRadioButton qz,hs;
private JPanel CenterJP,SouthJP;
private Kitchen cf; //厨房
private CrabCooking qzx,hsx; //大闸蟹加工者
CrabCookingStrategy()
{
f=new JFrame("策略模式在大闸蟹做菜中的应用");
f.setBounds(100,100,500,400);
f.setVisible(true);
f.setResizable(false);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
SouthJP=new JPanel();
CenterJP=new JPanel();
f.add("South",SouthJP);
f.add("Center",CenterJP);
qz=new JRadioButton("清蒸大闸蟹");
hs=new JRadioButton("红烧大闸蟹");
qz.addItemListener(this);
hs.addItemListener(this);
ButtonGroup group=new ButtonGroup();
group.add(qz);
group.add(hs);
SouthJP.add(qz);
SouthJP.add(hs);
//---------------------------------
cf=new Kitchen(); //厨房
qzx=new SteamedCrabs(); //清蒸大闸蟹类
hsx=new BraisedCrabs(); //红烧大闸蟹类
}
public void itemStateChanged(ItemEvent e)
{
JRadioButton jc=(JRadioButton) e.getSource();
if(jc==qz)
{
cf.setStrategy(qzx);
cf.CookingMethod(); //清蒸
}
else if(jc==hs)
{
cf.setStrategy(hsx);
cf.CookingMethod(); //红烧
}
CenterJP.removeAll();
CenterJP.repaint();
CenterJP.add((Component)cf.getStrategy());
f.setVisible(true);
}
public static void main(String[] args)
{
new CrabCookingStrategy();
}
}
//抽象策略类:大闸蟹加工类
interface CrabCooking
{
public void CookingMethod(); //做菜方法
}
//具体策略类:清蒸大闸蟹
class SteamedCrabs extends JLabel implements CrabCooking
{
private static final long serialVersionUID=1L;
public void CookingMethod()
{
this.setIcon(new ImageIcon("src/strategy/SteamedCrabs.jpg"));
this.setHorizontalAlignment(CENTER);
}
}
//具体策略类:红烧大闸蟹
class BraisedCrabs extends JLabel implements CrabCooking
{
private static final long serialVersionUID=1L;
public void CookingMethod()
{
this.setIcon(new ImageIcon("src/strategy/BraisedCrabs.jpg"));
this.setHorizontalAlignment(CENTER);
}
}
//环境类:厨房
class Kitchen
{
private CrabCooking strategy; //抽象策略
public void setStrategy(CrabCooking strategy)
{
this.strategy=strategy;
}
public CrabCooking getStrategy()
{
return strategy;
}
public void CookingMethod()
{
strategy.CookingMethod(); //做菜
}
}
[実施例2]婺源旅行に韶関旅行からポリシーモードを実施しました。
分析:韶関から婺源観光旅行、いくつかの方法に:図4に示すように、ポリシーモードにインスタンスが、より適しているように電車、バス、車によって、その構造です。
アプリケーションシナリオの戦略モード
戦略モードは、次のような多くの場所で使用され たJava 複数のレイアウトを選択するユーザの存在各容器内の典型的な例では、Java SEのあるSE管理コンテナレイアウト。プログラミングには、次の場合には、より一般的に使用される戦略パターン。
- システムは、動的時間にいくつかのアルゴリズムのいずれかを選択する必要がある各アルゴリズムのクラスポリシーにパッケージすることができます。
- クラスは、行動の数及びこのクラスの動作における条件文の複数の形でこれらの動作を定義し、各条件分岐は、条件文の代わりに、それぞれのポリシークラスに移動させることができます。
- 完全に互いに独立して、顧客を隠す実装の詳細特定のアルゴリズム要件の各アルゴリズムシステム。
- システムは、その運用中のデータは、戦略パターンは、関連付けられたアルゴリズムを隠すために使用することができたときに知っているべきではないアルゴリズムを使用するように顧客を必要とするデータ構造を。
- その他のさまざまな動作の性能の一つのクラスの唯一の違いよりも、あなたは、Strategyパターンを使用することができ、実行時に動的に動作を実行するために特定を選択します。
拡大戦略モード
多くのクライアントは、アルゴリズムが非常に複雑になるだろう、すべてのポリシーを管理する戦略がある場合、ポリシーモードを使用したシステムでは、環境部門のポリシーファクトリパターンはこれらのポリシーを管理する場合は、クラスが大幅に作業クライアントの複雑さを軽減します図5に示す構造。