看破設(shè)計(jì)模式之策略模式(strategy)

一、策略模式概述

模式定義: 定義算法族,分別封裝一起,讓它們可以相互替換;此模式讓算法的變化獨(dú)立于使用它的客戶
使用場(chǎng)景: 針對(duì)一個(gè)問題有多種解決方法,而區(qū)別僅僅在于算法(行為)不同
模式結(jié)構(gòu):
1.抽象策略類
定義了一個(gè)公共接口,各種不同的算法以不同的方式實(shí)現(xiàn)這個(gè)接口,環(huán)境角色使用這個(gè)接口調(diào)用不同的算法,一般使用接口或抽象類實(shí)現(xiàn)。
2.具體策略類
實(shí)現(xiàn)了抽象策略定義的接口,提供具體的算法實(shí)現(xiàn)。
3.環(huán)境類
持有一個(gè)抽象策略類的引用,最終給客戶端調(diào)用。

UML圖:

image.png

二、標(biāo)準(zhǔn)策略代碼實(shí)現(xiàn)

/**
 * 抽象策略類
 */
public interface IStrategy {
    int calculate(int num1, int num2);
}

/**
 * 具體實(shí)現(xiàn)類A
 */
public class AddStrategy implements IStrategy {
    @Override
    public int calculate(int num1, int num2) {
        System.out.println("加法");
        return num1 + num2;
    }
}
/**
 * 具體實(shí)現(xiàn)類B
 */
public class MinusStrategy implements IStrategy {
    @Override
    public int calculate(int num1, int num2) {
        System.out.println("減法");
        return num1 - num2;
    }
}
/**
 * 環(huán)境類(持有策略抽象類)
 */
public class Context {
    private IStrategy cal;

    public Context(IStrategy cal) {
        this.cal = cal;
    }
    public int excuteCalculate(int num1, int num2) {
        return cal.calculate(num1, num2);
    }
}

測(cè)試結(jié)果

public class ClientMain {
    public static void main(String[] args) {
        Context context = new Context(new AddStrategy());
        int result = context.excuteCalculate(30, 20);
        System.out.println(result);
    }
}

三、模式理解重點(diǎn)

策略模式的重心不是如何實(shí)現(xiàn)算法,而是如何組織這些算法,從而讓程序結(jié)構(gòu)更加靈活,具有更好的維護(hù)性和擴(kuò)展性。
判斷是不是策略模式,只要看一個(gè)類里是否持有了抽象對(duì)象的關(guān)聯(lián)或者依賴,且當(dāng)客戶使用這個(gè)類使用實(shí)例化了這個(gè)屬性。

四、策略模式j(luò)ava用例

1.Comparator的使用

java中比較的使用就是典型的策略模式,我們實(shí)例化了Comparator(抽象策略類)接口傳遞給TreeSet(環(huán)境類)。

        TreeSet<Person> treeSet=new TreeSet<>(new Comparator<Person>(){
            @Override
            public int compare(Person o1, Person o2) {
                return o1.getAge()-o2.getAge();
            }
        });

查看源碼可以發(fā)現(xiàn)TreeSet間接持有了Comparator對(duì)象

public class TreeSet<E> extends AbstractSet<E>
    implements NavigableSet<E>, Cloneable, java.io.Serializable
{
    public TreeSet(Comparator<? super E> comparator) {
        this(new TreeMap<>(comparator));
    }
}

public class TreeMap<K,V> extends AbstractMap<K,V>
    implements NavigableMap<K,V>, Cloneable, java.io.Serializable
{
    private final Comparator<? super K> comparator;
    public TreeMap(Comparator<? super K> comparator) {
        this.comparator = comparator;
    }
}

2.Arrays.sort()中Comparator的使用

        Arrays.sort(null, new Comparator<Person>() {
            @Override
             public int compare(Person o1, Person o2) {
                return o1.getAge()-o2.getAge();
            }
        });

查看源碼可以發(fā)現(xiàn)Arrays雖然沒有持有Comparator對(duì)象,而是通過靜態(tài)方法執(zhí)行,但是思想上還是使用策略模式

public static <T> void sort(T[] a, Comparator<? super T> c) {
        if (c == null) {
            sort(a);
        } else {
            if (LegacyMergeSort.userRequested)
                legacyMergeSort(a, c);
            else
                TimSort.sort(a, 0, a.length, c, null, 0, 0);
        }
    }

五、變通

根據(jù)實(shí)際使用策略模式也并非一成不變,只要是使用了策略思想都可以歸為該模式;下面這種方式是環(huán)境類持有抽象類的依賴。

/**
 * 環(huán)境類(持有策略抽象類)
 */
public class Context {
    public static int excuteCal(IStrategy cal,int num1,int num2){
        return cal.calculate(num1,num2);
    }
}
**測(cè)試結(jié)果**
public class ClientMain {
    public static void main(String[] args) {
        int result = Context.excuteCal(new AddStrategy(),30,20);
        System.out.println(result);
    }
}

//TODO

六、心得參考

http://c.biancheng.net/view/1378.html
https://blog.csdn.net/u012124438/article/details/70039943/
HeadFirst設(shè)計(jì)模式

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 設(shè)計(jì)模式概述 在學(xué)習(xí)面向?qū)ο笃叽笤O(shè)計(jì)原則時(shí)需要注意以下幾點(diǎn):a) 高內(nèi)聚、低耦合和單一職能的“沖突”實(shí)際上,這兩者...
    彥幀閱讀 3,873評(píng)論 0 14
  • 在一個(gè)方法內(nèi)部定義的變量都存儲(chǔ)在棧中,當(dāng)這個(gè)函數(shù)運(yùn)行結(jié)束后,其對(duì)應(yīng)的棧就會(huì)被回收,此時(shí),在其方法體中定義的變量將不...
    Y了個(gè)J閱讀 4,547評(píng)論 1 14
  • 1 場(chǎng)景問題 1.1 報(bào)價(jià)管理 向客戶報(bào)價(jià),對(duì)于銷售部門的人來(lái)講,這是一個(gè)非常重大、非常復(fù)雜的問題,對(duì)不同的客戶要...
    4e70992f13e7閱讀 3,207評(píng)論 2 16
  • 寫在前面 項(xiàng)目地址Metal專輯音視頻專輯 正文 概述 Metal功能非常強(qiáng)大,在iOS平臺(tái)大有替代Opengl ...
    張芳濤閱讀 2,240評(píng)論 0 9
  • 似夢(mèng)非夢(mèng) 似夢(mèng) 溫柔似往昔 非夢(mèng) 冰冷的難以解凍 夢(mèng)里夢(mèng)外 虛無(wú)縹緲 最難懂
    青禾吖閱讀 284評(píng)論 2 6

友情鏈接更多精彩內(nèi)容