設(shè)計(jì)模式-策略模式(Strategy Pattern)

上一篇 <<<責(zé)任鏈模式(Chain of Responsibility Pattern)
下一篇 >>>模板方法模式(Template Pattern)


策略模式:定義了一系列的算法,并將每一個(gè)算法封裝起來(lái),而且使它們還可以相互替換。策略模式讓算法獨(dú)立于使用它的客戶而獨(dú)立變化。

策略模式在Spring的使用場(chǎng)景

把多重if判斷分割成多個(gè)不同的對(duì)象管理

  • ApplicationContext

FileSystemXmlApplicationContext
ClassPathXmlApplicationContext
XmlWebApplicationContext
……

  • Resource

UrlResource:訪問網(wǎng)絡(luò)資源的實(shí)現(xiàn)類。
ClassPathResource:訪問類加載路徑里資源的實(shí)現(xiàn)類。
FileSystemResource:訪問文件系統(tǒng)里資源的實(shí)現(xiàn)類。
ServletContextResource:訪問相對(duì)于 ServletContext 路徑里的資源的實(shí)現(xiàn)類:
InputStreamResource:訪問輸入流資源的實(shí)現(xiàn)類。
ByteArrayResource:訪問字節(jié)數(shù)組資源的實(shí)現(xiàn)類。

  • 初始化策略:
    SimpleInstantiationStrategy 簡(jiǎn)單初始化策略
    CglibSubclassingInstantiationStrategy CGLIB初始化策略

策略模式在項(xiàng)目中的使用場(chǎng)景

1.聯(lián)合登錄 QQ聯(lián)合登錄/微信聯(lián)合登錄/釘釘聯(lián)合登錄
2.排序算法 冒泡/簡(jiǎn)單選擇/堆排序等
3.聚合支付 支付寶/微信支付/銀聯(lián)支付/平安支付等
4.快遞 申通、圓通、京東、德邦、順豐等
5.發(fā)送通知 短信、微信公眾號(hào)模板、釘釘通知、郵件

策略模式優(yōu)缺點(diǎn)

優(yōu)點(diǎn):
1.算法可以自由切換(高層屏蔽算法,角色自由切換)
2.避免使用多重條件判斷(如果算法過(guò)多就會(huì)出現(xiàn)很多種相同的判斷,很難維護(hù))
3.擴(kuò)展性好(可自由添加取消算法 而不影響整個(gè)功能)

缺點(diǎn):
1、所有的策略都需要暴露給外面;
2、需要配合工廠模式或代理模式;
3、代碼量增加

策略模式與狀態(tài)模式的區(qū)別

a、狀態(tài)模式不同狀態(tài)下做的事情不同,而策略模式做的都是同一件事。
狀態(tài)模式重點(diǎn)在各狀態(tài)之間的切換從而做不同的事情,而策略模式更側(cè)重于根據(jù)具體情況選擇策略,并不涉及切換。
b、狀態(tài)模式封裝了對(duì)象的狀態(tài),而策略模式封裝算法或策略。
c、在狀態(tài)模式中,每個(gè)狀態(tài)通過(guò)持有Context的引用,來(lái)實(shí)現(xiàn)狀態(tài)轉(zhuǎn)移;但是每個(gè)策略都不持有Context的引用,它們只是被Context使用。

策略模式實(shí)現(xiàn)方式核心代碼

1. Strategy定義

public interface PayStrategy {
    /**
     * 共同算法實(shí)現(xiàn)骨架
     * @return
     */
     public String toPayHtml();
}

2.ConcreteStrategyA定義

@Component
public class AliPayStrategy  implements PayStrategy {
    @Override
    public String toPayHtml() {
        return "調(diào)用支付寶支付接口";
    }
}

3.Context組裝

1)、枚舉+反射

public enum PayEnumStrategy {

    /**
     *  支付寶支付【也可以配置容器中的ID】
     */
    ALI_PAY("cn.jarye.strategy.impl.AliPayStrategy"),
    /**
     *  銀聯(lián)支付【也可以配置容器中的ID】
     */
    UNION_PAY("cn.jarye.strategy.impl.UnionPayStrategy");
    PayEnumStrategy(String className) {
        this.setClassName(className);
    }

    public String getClassName() {
        return className;
    }

    public void setClassName(String className) {
        this.className = className;
    }

    /**
     * class完整地址
     */
    private String className;

}
public static PayStrategy getPayStrategy(String strategyType) {
    try {
        // 1.獲取枚舉中className
        String className = PayEnumStrategy.valueOf(strategyType).getClassName();
        // 2.使用java反射技術(shù)初始化類【也可以根據(jù)容器中的ID獲取bean】
        return (PayStrategy) Class.forName(className).newInstance();
    } catch (Exception e) {
        return null;
    }
}

2)、數(shù)據(jù)庫(kù)配置

// 1.使用PayCode查詢
PaymentChannelEntity paymentChannel = paymentChannelMapper.getPaymentChannel(payCode);
if(paymentChannel==null){
    return  "該渠道為空...";
}
// 2.獲取策略執(zhí)行的beanid
String strategyBeanId = paymentChannel.getStrategyBeanId();
// 3.使用strategyBeanId獲取對(duì)應(yīng)spring容器bean信息
PayStrategy payStrategy = springUtils.getBean(strategyBeanId, PayStrategy.class);

相關(guān)文章鏈接:
<<<23種常用設(shè)計(jì)模式總覽
<<<代理模式(Proxy Pattern)
<<<裝飾模式(Decorator Pattern)
<<<觀察者模式(Observer Pattern)
<<<單例模式(Singleton Pattern)
<<<責(zé)任鏈模式(Chain of Responsibility Pattern)
<<<模板方法模式(Template Pattern)
<<<外觀/門面模式(Facade Pattern)
<<<建造者模式(Builder Pattern)
<<<適配器模式(Adapter Pattern)
<<<原型模式(Prototype Pattern)
<<<工廠相關(guān)模式(Factory Pattern)

最后編輯于
?著作權(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)容

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