有道無術,術可求
有術無道,止于術
一、策略模式的定義
先舉一個例子來說:在網上購物的時候,有的時候會有一些打折的活動,可能會給你5元的優惠券,也有可能會給一張滿減的優惠券,而無論給怎樣的優惠券,到了開發人員的那邊,這不過是它們寫好的一些或者是封裝好的一些類,這些這都是可以隨時替換的,想搞一個其它的活動,就把它們替換成其它的類,當然,這只是舉一個例子,實際的代碼實作是很復雜的,
策略的定義,定義了很多的演算法,將它們分別的封裝了起來,它們之間可以互相的替換
在策略模式中,寫好的演算法是和我們操作的物件是會分開的,可以看下寫好的策略模式的UML:

在上面的UML中可以看到演算法和物件的本身之間是區分開來的,所以這里是分成了三個部分:
- 環境(Context):可以來操作策略
- 抽象策略(Strategy):這里面定義了具體策略要實作的方法
- 具體策略(ConcreteStrategy):實作了Strategy,將Strategy里面的方法都實作
二、策略模式的應用場景
- 系統中有很多的類,這些類的區別只是在具體的代碼實作上不一至
- 其中有的系統可能會有多種演算法,通過策略模式可以在這些類中任意選擇
優點:
- 可以在不修改原有系統的情況下,選擇具體的行為
- 可以大量的消除條件陳述句,if....else switch
- 可以降低代碼的耦合
缺點:
- 在使用的時候客戶端要知道有那些類
- 可能會發生類爆炸
三、策略模式的代碼實作
定義Strategy
這個是我們上面所說的抽象策略,里面是具體策略要實作的方法,它是一個介面
public interface BreadIngredients {
public void addIngredients();
}
定義ConcreteStrategy
在這個里面我們有了具體的實作,里面就是我們要實作的一些演算法,這個類可以有多個,但是要實作Strategy介面
public class NiuRouIngredients implements BreadIngredients {
@Override
public void addIngredients() {
System.out.println("添加了牛肉的配料");
}
}
public class SaLaIngredients implements BreadIngredients {
@Override
public void addIngredients() {
System.out.println("添加了沙拉的配料");
}
}
定義Context
這個里面我們要操作策略類
可以看出這個在這個類中聚合了BreadIngredients,只要傳入一個BreadIngredients的子類就可以了
public class BreadFactory {
private BreadIngredients breadIngredients;
public BreadFactory(BreadIngredients breadIngredients){
this.breadIngredients = breadIngredients;
}
public void ProcessingBread(){
breadIngredients.addIngredients();
}
}
這個是一個客戶端類,我們在這個類里面進行測驗
public class Client {
public static void main(String[] args) {
BreadFactory niuRoubread = new BreadFactory(new NiuRouIngredients());
BreadFactory saLabread = new BreadFactory(new SaLaIngredients());
niuRoubread.ProcessingBread();
saLabread.ProcessingBread();
}
}

通過上面的代碼大概對策略模式有了相應的了解,就是說在處理一些問題的時候可能會有好多的解法,只要選擇了里面的一種就可以了,
四、使用策略模式和工廠模式混合使用
在有的時候,寫代碼的程序中使用了策略模式還是避免不了有很多的if....else,為了避免這種冗余的代碼,這使用工廠模式和策略模式的情況下可以避免這種情況

創建一個空的具體抽象策略
public class NONELngredients implements BreadIngredients{
@Override
public void addIngredients() {
System.out.println("沒有此項");
}
}
這里我就創建一個工廠類
public class BreadFactoryAndCeLue {
//這個MAP要保存用的策略模式的類
private static Map<String,BreadIngredients> MAP_BREAD = new HashMap<String,BreadIngredients>();
//因為在下面的靜態方法中,如果找不到Map中的資料,就會回傳一個空的類
private static BreadIngredients NONE = new NONELngredients();
static {
MAP_BREAD.put(Map_Key.niurou,new NiuRouIngredients());
MAP_BREAD.put(Map_Key.sala,new SaLaIngredients());
}
//因為這個是工廠類,所以私有化構造方法
private BreadFactoryAndCeLue(){}
public static BreadIngredients getBreadIngredients(String key){
BreadIngredients breadIngredients = MAP_BREAD.get(key);
return breadIngredients == null ? NONE : breadIngredients;
}
public interface Map_Key{
public String niurou = "niurou";
public String sala = "sala";
}
}
可以看出在下面的測驗的方法里面,if...else減少了
測驗方法
public static void main(String[] args) {
String key = "niurou";
BreadIngredients breadIngredients = BreadFactoryAndCeLue.getBreadIngredients(key);
breadIngredients.addIngredients();
}
結果

注:在使用策略模式的時候,如果類有很多,就要考濾可不可以使用策略模式結合其它的模式配合使用
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/4541.html
標籤:設計模式
上一篇:中介者模式
下一篇:設計模式(3) 抽象工廠模式
