設計模式之策略模式

  策略(Strategy)模式,指對象有某個行爲,可是在不一樣的場景中,該行爲有不一樣的實現算法時處理策略。簡單來講,策略模式定義了一個算法家族,並讓這些算法能夠互換java

       傳統模式是經過繼承處理多種算法或行爲。該方式須要大量的子類,每個子類提供一個不一樣的算法或行爲。可是,這樣一來算法或行爲的使用者就和算法或行爲自己混在一塊兒繼承使得動態改變算法或行爲變得不可能(每個子類只能實現特定的算法)算法

        策略模式是對一系列算法的封裝,即:爲全部的算法定義一個抽象的算法接口(能夠是接口,也能夠是抽象類),並由具體的策略對象對算法進行實現。具體的算法選擇交由具體策略類決定(具體策略類持有策略接口的引用)。編程

  本模式的核心思想是:多態(面向接口編程),組合【替代繼承關係】
設計模式

 

1. 傳統模式【經過繼承實現】ide

    1.1 抽象類【Duck.java】this

    將共有的方法抽到這個類裏面。(該類做爲超類,其它類能夠繼承該類,實現對抽象類方法的繼承或重寫)spa

public abstract class Duck {

    public abstract void swim();

    public void scream() {
        //TODO
    }
}

    1.2 實體對象類【FlyDuck.java】設計

           繼承抽象類,實現本身的特有邏輯code

public class FlyDuck extends Duck {

    @Override
    public void swim() {
        // TODO 
    }
}

    1.3 Demo對象

public static void main(String[] args) {
    FlyDuck duck = new FlyDuck();
    duck.siwm();
}

 

2. 策略模式

        將對象分爲三種角色:1.抽象策略角色,2.具體策略角色,3.環境角色

    2.1 抽象策略角色

       爲算法定義一個抽象的算法接口

public interface PriceStrategy {
    
    BigDecimal getCurrentPrice(BigDecimal price) throws Exception;
    
}

    2.2 具體策略角色

       實現抽象策略角色,根據具體的業務需求,實現特定的算法

public class NewYearPriceStrategy implements PriceStrategy{

    @Override
    public BigDecimal getCurrentPrice(BigDecimal price) throws Exception {
        if(price == null){
            throw new Exception("Prince is null.Please Check.");
        }
        BigDecimal discount = new BigDecimal(0.5);
        return price.multiply(discount);
    }

}

    2.3 環境角色

      策略的外部封裝類,或者說策略的容器類。根據不一樣策略執行不一樣的行爲。

public class Commodity {

    private BigDecimal price;
//策略角色的引用,多態原理
private PriceStrategy strategy; public Commodity(BigDecimal price, PriceStrategy strategy) { super(); this.price = price; this.strategy = strategy; } public BigDecimal getCurrentPrince() throws Exception{ if(strategy == null){ throw new Exception("Prince Calculator is null. Please check."); } return strategy.getCurrentPrice(price); } }

    2.4 Demo

public class Demo {

    public static void main(String[] args) throws Exception {
        Commodity commodity = new Commodity(new BigDecimal(124.00),new NewYearPriceStrategy());
        System.out.println(commodity.getCurrentPrince());
    }
}

 

3. 補充

    3.1 繼承是在編譯時靜態決定類的行爲,組合是在運行時動態地拓展對象的行爲。並且,經過動態地組合對象,能夠寫新的代碼添加新功能,而無須修改現有的代碼(出現Bug的機率會變低)。

 

4. 參考資料

    4.1 北風網在線培訓《策略模式》

    4.2 百度百科《策略模式》

    4.3 O'Reilly《Head First設計模式》

相關文章
相關標籤/搜索