策略模式定義了一系列的演算法,並將每一個演算法封裝起來,而且使它們還可以相互替換。策略模式讓演算法獨立於使用它的客戶而獨立變化。(原文:The Strategy Pattern defines a family of algorithms,encapsulates each one,and makes them interchangeable. Strategy lets the algorithm vary independently from clients that use it.) Context(應用情境): 1、需要使用ConcreteStrategy提供的演算法。
2、內部維護一個Strategy的執行個體。
3、負責動態設定運行時Strategy具體的實現演算法。
4、負責跟Strategy之間的互動和資料傳遞。
Strategy(抽象策略類):
1、定義了一個公用介面,各種不同的演算法以不同的方式實現這個介面,Context使用這個介面調用不同的演算法,一般使用介面或抽象類別實現。
ConcreteStrategy(具體策略類):
2、 實現了Strategy定義的介面,提供具體的演算法實現。
應用情境:
1、多個類只區別在表現行為不同,可以使用Strategy模式,在運行時動態選擇具體要執行的行為。(例如FlyBehavior和QuackBehavior)
2、需要在不同情況下使用不同的策略(演算法),或者策略還可能在未來用其它方式來實現。(例如FlyBehavior和QuackBehavior的具體實現可任意變化或擴充)
3、 對客戶(Duck)隱藏具體策略(演算法)的實現細節,彼此完全獨立。
UML圖示:
策略模式的實現
–策略模式的用意是針對一組演算法,將每一個演算法封裝到具有共同介面的獨立的類中,從而使得它們可以相互替換。
–策略模式使得演算法可以在不影響到用戶端的情況下發生變化。使用原則模式可以把行為和環境分割開來。
–環境類負責維持和查詢行為類,各種演算法則在具體策略中提供。由於演算法和環境獨立開來,演算法的修改都不會影響環境和用戶端
策略模式的編寫步驟
–1.對策略對象定義一個公用介面。
–2.編寫策略類,該類實現了上面的公用介面
–3.在使用原則對象的類中儲存一個對策略對象的引用。
–4.在使用原則對象的類中,實現對策略對象的set和get方法(注入)或者使用構造方法完成賦值
•策略模式的缺點
–1.用戶端必須知道所有的策略類,並自行決定使用哪一個策略類。
–2.造成很多的策略類。
•解決方案
–採用Factory 方法
測試:示範兩個數的加、減、乘、除運算
一:
建立一個策略的介面
package collection2;
public interface Strategy
{
public int calculate(int a,int b);
}
二:
實現一組策略的方法類
package collection2;
public class AddStrategy implements Strategy
{
public int calculate(int a, int b)
{
return a + b;
}
}
package collection2;
public class SubtractStrategy implements Strategy
{
public int calculate(int a, int b)
{
return a - b;
}
}
package collection2;
public class MultiplyStrategy implements Strategy
{
public int calculate(int a, int b)
{
return a * b;
}
}
package collection2;
public class DivideStrategy implements Strategy
{
public int calculate(int a, int b)
{
return a / b;
}
}
三:
定義一個策略對象類,實現對策略對象的set和get方法(注入)或者使用構造方法完成賦值
package collection2;
public class Environment
{
private Strategy strategy;
public Environment(Strategy strategy)
{
this.setStrategy(strategy);
}
public void setStrategy(Strategy strategy)
{
this.strategy = strategy;
}
public Strategy getStrategy()
{
return strategy;
}
public int calculate(int a, int b)
{
return strategy.calculate(a, b);
}
}
四:
構建一個策略的客服端類,對我們上面定義的策略模式進行測試
package collection2;
public class Client
{
public static void main(String[] args)
{
AddStrategy addStrategy = new AddStrategy();
// 加法策略
Environment environment = new Environment(addStrategy);
System.out.println("加法策略" + environment.calculate(8, 2));
// 減法策略
SubtractStrategy subtractStrategy = new SubtractStrategy();
environment.setStrategy(subtractStrategy);
System.out.println("減法策略:" + environment.calculate(8, 2));
// 乘法策略
MultiplyStrategy multiplyStrategy = new MultiplyStrategy();
environment.setStrategy(multiplyStrategy);
System.out.println("乘法策略:" + environment.calculate(8, 2));
// 除法策略
DivideStrategy divideStrategy = new DivideStrategy();
environment.setStrategy(divideStrategy);
System.out.println("除法策略:" + environment.calculate(8, 2));
}
}
測試結果:
加法策略10
減法策略:6
乘法策略:16
除法策略:4