策略模式

有道無術,術可求
有術無道,止於術java

1、策略模式的定義

先舉一個例子來講:在網上購物的時候,有的時候會有一些打折的活動,可能會給你5元的優惠券,也有可能會給一張滿減的優惠券,而不管給怎樣的優惠券,到了開發人員的那邊,這不過是它們寫好的一些或者是封裝好的一些類,這些這都是能夠隨時替換的,想搞一個其它的活動,就把它們替換成其它的類,固然,這只是舉一個例子,實際的代碼實現是很複雜的。算法

策略的定義,定義了不少的算法,將它們分別的封裝了起來,它們之間能夠互相的替換ide

在策略模式中,寫好的算法是和咱們操做的對象是會分開的,能夠看下寫好的策略模式的UML:測試

策略模式UML

在上面的UML中能夠看到算法和對象的自己之間是區分開來的,因此這裏是分紅了三個部分:this

  • 環境(Context):能夠來操做策略
  • 抽象策略(Strategy):這裏面定義了具體策略要實現的方法
  • 具體策略(ConcreteStrategy):實現了Strategy,將Strategy裏面的方法都實現

2、策略模式的應用場景

  • 系統中有不少的類,這些類的區別只是在具體的代碼實現上不一至
  • 其中有的系統可能會有多種算法,經過策略模式能夠在這些類中任意選擇

優勢:code

  • 能夠在不修改原有系統的狀況下,選擇具體的行爲
  • 能夠大量的消除條件語句,if....else switch
  • 能夠下降代碼的耦合

缺點:對象

  • 在使用的時候客戶端要知道有那些類
  • 可能會發生類爆炸

3、策略模式的代碼實現

定義Strategy
這個是咱們上面所說的抽象策略,裏面是具體策略要實現的方法,它是一個接口blog

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();
    }
}

經過上面的代碼大概對策略模式有了相應的瞭解,就是說在處理一些問題的時候可能會有好多的解法,只要選擇了裏面的一種就能夠了。

4、使用策略模式和工廠模式混合使用

在有的時候,寫代碼的過程當中使用了策略模式仍是避免不了有不少的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();
    }

結果

注:在使用策略模式的時候,若是類有不少,就要考濾可不能夠使用策略模式結合其它的模式配合使用

相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息