模板下載免費網(wǎng)站百度瀏覽器廣告怎么投放
策略模式是什么
策略模式(Strategy):針對一組算法,將每一個算法封裝起來,從而使得它們可以相互替換。
比如我們一個軟件的會員等級,每一個等級都會有對應(yīng)的一些等級權(quán)益,那么每一個等級權(quán)益就對應(yīng)一個策略
結(jié)構(gòu)
策略模式的通用類圖如下:
策略模式主要由這三個角色組成,環(huán)境角色(Context)、抽象策略角色(Strategy)和具體策略角色(ConcreteStrategy)
1.上下文角色(Context):持有所有策略類的對象,可以根據(jù)策略提供相應(yīng)的算法給客戶端使用。
2.抽象策略角色(Strategy):這是一個抽象角色,通常由一個接口或抽象類實現(xiàn)。此角色提供具體策略類所需的接口。
3.具體策略角色(ConcreteStrategy):繼承或?qū)崿F(xiàn)了抽象策略,封裝了相應(yīng)的算法或行為。
策略模式的優(yōu)缺點
優(yōu)點
(1)算法可以自由切換
(2)避免使用多重條件判斷
(3)擴展性良好,增加一個策略只需實現(xiàn)接口即可
缺點
(1)策略類數(shù)量會增多,每個策略都是一個類,復(fù)用性很小
(2)所有的策略類都需要對外暴露
使用場景
1、業(yè)務(wù)代碼需要根據(jù)場景不同,切換不同的實現(xiàn)邏輯
2、代碼中存在大量 if else 邏輯判斷
實例
下面使用策略模式實現(xiàn)會員不同等級的權(quán)益領(lǐng)取
抽象策略角色:
/*** 會員抽象策略*/
public interface MemberStrategy {/*** 領(lǐng)取會員福利*/void getWeal();}
具體策略角色:
/*** 等級1的會員福利*/
@Component
public class LV1MemberWeal implements MemberStrategy {@Overridepublic void getWeal() {System.out.println("5元優(yōu)惠券");}}/*** 等級2會員福利*/
@Component
public class LV2MemberWeal implements MemberStrategy{@Overridepublic void getWeal() {System.out.println("10元優(yōu)惠券");}}
上下文角色:
我們可以使用枚舉加bean工廠來定義一個上下文角色,避免上下文角色的if-else
策略枚舉類
策略枚舉類用于獲取bean容器中的策略類class
/*** 策略枚舉*/
public enum MemberEnum {LV1(LV1MemberWeal.class),LV2(LV2MemberWeal.class);;private Class clazz;MemberEnum(Class clazz) {this.clazz = clazz;}public static Class getStrategyClass(String name){return MemberEnum.valueOf(name).clazz;}}
使用ApplicationContext可以獲取bean工廠中的實例,下面是對應(yīng)工具類
@Component
public class ApplicationContextUtil implements ApplicationContextAware {private static ApplicationContext applicationContext;/*** 將ApplicationContext注入* @param applicationContext* @throws BeansException*/@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {this.applicationContext = applicationContext;}public static ApplicationContext getApplicationContext(){return applicationContext;}/*** 根據(jù)類型獲取bean* @param clazz* @param <T>* @return*/public static <T> T getBean(Class clazz){return (T) getApplicationContext().getBean(clazz);}/*** 根據(jù)名稱獲取bean* @param name* @param <T>* @return*/public static <T> T getBean(String name){return (T) getApplicationContext().getBean(name);}}
上下文角色類
/*** 會員上下文角色*/
@Component
public class MemberStrategyContext {/*** 根據(jù)入?yún)㈩愋瞳@取對應(yīng)的策略類* @param type* @return*/public MemberStrategy getMemberStrategy(String type){MemberStrategy memberStrategy = ApplicationContextUtil.getBean(MemberEnum.getStrategyClass(type));return memberStrategy;}}
測試類
RunWith(SpringRunner.class) //作用:讓當(dāng)前類在容器環(huán)境下進(jìn)行測試
@SpringBootTest(classes = DemoApplication.class)
public class StrategyTest {@Autowiredprivate MemberStrategyContext memberStrategyContext;@Testpublic void testStrategy(){//根據(jù)入?yún)@取對應(yīng)策略類MemberStrategy memberStrategy = memberStrategyContext.getMemberStrategy("LV2");//執(zhí)行策略類的算法memberStrategy.getWeal();}}