上一篇 <<<責(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)