設計模式之策略模式(STRATEGY),設計模式strategy

來源:互聯網
上載者:User

設計模式之策略模式(STRATEGY),設計模式strategy

1.適用性

當存在以下情況時使用STRATEGY模式

a.許多相關的類僅僅是行為有異。“策略”提供了一種用多個行為中的一個行為來配置一個類的方法。

b.需要使用一個演算法的不同變體。例如,你可能會定義一些反映不同的空間/時間權衡的演算法。當這些變體實現為一個演算法的類層次時,可以使用原則模式。

c.演算法使用客戶不應該知道的資料。可以使用原則模式以避免暴露複雜的、與演算法相關的資料結構。

d.一個類定義了多種行為,並且這些行為在這個類的操作中以多個條件陳述式的形式出現。將相關的條件分支移入它們各自的Strategy類中以替代這些條件陳述式。

2.參與者

 Strategy(策略): 定義所有支援的演算法的公用介面。Context使用這個介面來調用某種ConcreteStrategy定義的演算法。

 ConcreteStrategy(具體策略):以Strategy介面實現某種具體演算法。

 Context(上下文):用一個ConcreteStategy對象來配置;維護一個對Strategy對象的引用;可定義一個介面讓Strategy訪問它的資料。

3.優缺點

 優點: 

a.相關演算法系列:Strategy類層次為Context定義了一系列的可供重用的演算法或行為。繼承有助於析取演算法中的公用的功能。

b.一個替代繼承的方法:可以直接產生一個Context的子類,從而給它以不同的行為。但是,這會將行為寫入程式碼到Context中,而將演算法的實現和Context的實現混合起來,使得Context難以理解、維護和擴充,而且還不能動態改變演算法。

c.消除了一些條件陳述式:沒有使用strategy模式的代碼很有可能會被設計成在一個類中,使用if判斷條件執行相應的策略。

d.實現的選擇:用戶端可以根據要求從不同的策略中進行選擇。

 缺點:

a.Strategy和Context之間的通訊開銷: 無論各個ConcreteStrategy實現的演算法是簡單還是複雜,他們都會共用Strategy定義的介面。因此很可能某些ConcreteStrategy不會都用到所有通過這個介面傳遞給他們的資訊。簡單的ConcreteStrategy可能不會使用其中的任何資訊,這就意味著有時Context會建立和初始化一些永遠不會用到的參數。如果存在這樣的問題,那麼將需要在Strategy和Context之間進行緊密的耦合。

b.增加了對象的數目

4.執行個體

package strategy;/** * Description: 策略介面類 * * @author  * @version 1.0 * @since 2017-08-02 5:46 PM */public interface Strategy {    void algorithmInterface();}

package strategy;/** * Description: 具體策略A * * @author  * @version 1.0 * @since 2017-08-02 5:47 PM */public class ConcreteStrategyA implements Strategy {    @Override    public void algorithmInterface() {        System.out.println("策略A執行");    }}

package strategy;/** * Description: 具體策略B * * @author  * @version 1.0 * @since 2017-08-02 5:48 PM */public class ConcreteStrategyB implements Strategy {    @Override    public void algorithmInterface() {        System.out.println("策略B執行");    }}

package strategy;/** * Description: 具體策略C * * @author  * @version 1.0 * @since 2017-08-02 5:49 PM */public class ConcreteStrategyC implements Strategy {    @Override    public void algorithmInterface() {        System.out.println("策略C執行");    }}

package strategy;/** * Description: 上下文配置類 * * @author yunqiangdi * @version 1.0 * @since 2017-08-02 5:49 PM */public class Context {    //持有策略介面的引用    private Strategy strategy;    /**     * 用其中某個策略初始化上下文     * @param strategy 具體的策略類     */    public Context(Strategy strategy) {        this.strategy = strategy;    }    /**     * 進行策略的具體執行     */    public void operator() {        strategy.algorithmInterface();    }}

package strategy;/** * Description: 策略測試類別 * * @author yunqiangdi * @version 1.0 * @since 2017-08-02 5:55 PM */public class StrategyTest {    public static void main(String[] args) {        Strategy strategy = new ConcreteStrategyA();        Context ctx = new Context(strategy);        ctx.operator();    }}


第二種表示策略的方式為使用匿名內部類表示策略(這種也可以把匿名內部類當作一個函數對象)。


package strategy.example2;/** * @author koou * @version 1.0 * @since 2017-08-05 下午 13:26 */public interface Strategy<T> {    /**     * 策略介面     * @param t 策略執行     */    <T> void process(T t);}

package strategy.example2;/** * @author koou * @version 1.0 * @since 2017-08-05 下午 13:27 */public class StrategyProcess {    /**     * @param t 策略的執行對象     * @param strategy 具體策略     */    public static <T> void apply(T t, Strategy<T> strategy) {        strategy.process(t);    }}


package strategy.example2;import java.util.Arrays;/** * @author koou * @version 1.0 * @since 2017-08-05 下午 13:30 */public class StrategyTest {    public static void main(String[] args) {        int[] iarray = {1, 2, 3, 4, 5};        //對int數組進行策略操作,修改數組第一個數字為9097        StrategyProcess.apply(iarray, new Strategy<int[]>() {            public <T> void process(T t) {                int[] temparray = (int[]) t;                if (temparray.length > 1) {                    temparray[0] = 9097;                }            }        });        System.out.println(Arrays.toString(iarray));    }}


輸出為:
[9097, 2, 3, 4, 5]


由匿名內部類每次執行的時候會建立一個新的執行個體,如果它被重複執行,考慮將函數Object Storage Service到一個私人的靜態final域中。


package strategy.example3;import java.io.Serializable;import java.util.Comparator;/** * @author koou * @version 1.0 * @since 2017-08-05 下午 17:03 */public class Host {    private static class StrLenCmp implements Comparator<String>, Serializable {        public int compare(String o1, String o2) {            return o1.length() - o2.length();        }    }    //具體的策略    public static final Comparator<String> STRING_LEN_COMPARATOR = new StrLenCmp();}


package strategy.example3;import java.util.Arrays;/** * @author koou * @version 1.0 * @since 2017-08-05 下午 17:09 */public class StrategyTest {    public static void main(String[] args) {        String[] strArray = {"I", "am", "sk", "I"};        Arrays.sort(strArray, Host.STRING_LEN_COMPARATOR);        System.out.println(Arrays.toString(strArray));    }}

測試結果:[I, I, am, sk] 查看評論

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.