Java設(shè)計(jì)模式中的策略(Strategy)模式解讀
Java的策略模式
策略(Strategy)模式:分離算法,選擇實(shí)現(xiàn) 比如對(duì)象的某個(gè)行為,在不同場(chǎng)景有不同實(shí)現(xiàn)方式,可以將這些行為的具體實(shí)現(xiàn)定義為一組策略,每個(gè)實(shí)現(xiàn)類實(shí)現(xiàn)一種策略,在不同場(chǎng)景使用不同的實(shí)現(xiàn),并且可以自由切換策略,但太多的策略會(huì)導(dǎo)致大量代碼
- 優(yōu)點(diǎn):
- 不用太多if else
- 代碼優(yōu)雅、簡(jiǎn)單
- 符合開(kāi)閉原則,擴(kuò)展性好、便于維護(hù)
- 缺點(diǎn):
- 策略如果很多的話,會(huì)造成策略類膨脹
- 使用者必須清楚所有的策略類及其用途
如:電商活動(dòng)打折,普通會(huì)員9折,黃金會(huì)員8折,鉆石會(huì)員7折
1.定義一個(gè)Strategy接口,只有打折方法
2.增加3個(gè)打折類,對(duì)應(yīng)9折、8折、7折
3.客戶端根據(jù)會(huì)員類型,獲取具體的策略算法實(shí)現(xiàn)類,再執(zhí)行打折方法
策略模式與Spring結(jié)合
/** * 打折策略枚舉 */ public enum ActivityStrategyEnum { MEMBER(1, "普通會(huì)員"), GOLD_MEMBER(2, "黃金會(huì)員"), DIAMOND_MEMBER(3, "鉆石會(huì)員"), ; private int code; private String name; ActivityStrategyEnum (int code, String name) { this.code = code; this.name = name; } /** * 通過(guò)code匹配對(duì)應(yīng)枚舉 * @param code * @return */ public static ActivityStrategyEnum match(int code){ ActivityStrategyEnum strategyEnum = null; for (ActivityStrategyEnum item : values()){ if(item.getCode() == code){ strategyEnum = item; break; } } return strategyEnum; } public int getCode() { return code; } public String getName() { return name; } }
//打折接口 public interface IActivityStrategyService { //策略code int getCode(); /** * 打折 * @param money * @return 應(yīng)付金額 */ BigDecimal calculate(BigDecimal money); } @Service("memberService ") public class MemberService implements IActivityStrategyService { @Override public int getCode() { return ActivityStrategyEnum.MEMBER.getCode(); } @Override public BigDecimal calculate(BigDecimal money) { //普通會(huì)員9折 return money.multiply(new BigDecimal(0.9)).setScale(2, RoundingMode.HALF_UP); } } @Service("goldMemberService") public class GoldMemberService implements IActivityStrategyService { @Override public int getCode() { return ActivityStrategyEnum.GOLD_MEMBER.getCode(); } @Override public BigDecimal calculate(BigDecimal money) { //黃金會(huì)員8折 return money.multiply(new BigDecimal(0.8)).setScale(2, RoundingMode.HALF_UP); } } @Service("diamondMemberService") public class DiamondMemberService implements IActivityStrategyService { @Override public int getCode() { return ActivityStrategyEnum.DIAMOND_MEMBER.getCode(); } @Override public BigDecimal calculate(BigDecimal money) { //鉆石會(huì)員7折 return money.multiply(new BigDecimal(0.7)).setScale(2, RoundingMode.HALF_UP); } }
import org.springframework.beans.BeansException; import org.springframework.beans.factory.InitializingBean; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.stereotype.Component; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @Component public class ActivityStrategyHandler implements InitializingBean, ApplicationContextAware { /** * 存放策略的map,可以理解為策略的注冊(cè)中心 */ private final Map<Integer, IActivityStrategyService> serviceHashMap = new ConcurrentHashMap<>(); /** * spring的上下文 */ private ApplicationContext applicationContext; /** * 將StrategyService的類都按照定義好的規(guī)則(枚舉code),放入strategyServiceMap中 * * @throws Exception */ @Override public void afterPropertiesSet() throws Exception { Map<String, IActivityStrategyService> matchBeans = applicationContext.getBeansOfType(IActivityStrategyService.class); for (IActivityStrategyService strategyService : matchBeans.values()) { serviceHashMap.put(strategyService.getCode(), strategyService); System.out.println("初始化策略模式的鍵值對(duì) code =" + strategyService.getCode() + " ,value=" + strategyService); } } /** * 注入applicationContext * * @param applicationContext * @throws BeansException */ @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } /** * 通過(guò)枚舉code獲取對(duì)應(yīng)對(duì)更新服務(wù) * @param strategyEnum * @return */ public IActivityStrategyService getActivityService(ActivityStrategyEnum strategyEnum){ return serviceHashMap.get(strategyEnum.getCode()); } }
客戶端調(diào)用
@RestController public class IndexController { @Autowired private ActivityStrategyHandler activityHandler; @GetMapping("/acitivity") public BigDecimal acitivity(int code) throws JsonProcessingException { //會(huì)員類型code ActivityStrategyEnum strategyEnum = ActivityStrategyEnum.match(code); IActivityStrategyService activityService = activityHandler.getActivityService(strategyEnum); //獲取商品金額 BigDecimal amount = new BigDecimal(100); //調(diào)用具體的打折策略算法 BigDecimal price = activityService.calculate(amount); return price ; } }
到此這篇關(guān)于Java設(shè)計(jì)模式中的策略(Strategy)模式解讀的文章就介紹到這了,更多相關(guān)Java的策略模式內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java簡(jiǎn)單計(jì)算器的實(shí)現(xiàn)
這篇文章主要為大家詳細(xì)介紹了Java簡(jiǎn)單計(jì)算器的實(shí)現(xiàn),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-12-12IntelliJ IDEA 部署 Web 項(xiàng)目,看這一篇夠了!
這篇文章主要介紹了IntelliJ IDEA 部署 Web 項(xiàng)目的圖文教程,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-05-05Spring Cloud 覆寫(xiě)遠(yuǎn)端的配置屬性實(shí)例詳解
這篇文章主要介紹了Spring Cloud 覆寫(xiě)遠(yuǎn)端的配置屬性的相關(guān)知識(shí),非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2018-01-01Java啟用Azure Linux虛擬機(jī)診斷設(shè)置
這篇文章主要介紹了Java啟用Azure Linux虛擬機(jī)診斷設(shè)置,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-05-05Java調(diào)用第三方http接口的四種方式總結(jié)
這篇文章主要給大家介紹了關(guān)于Java調(diào)用第三方http接口的四種方式,在實(shí)際開(kāi)發(fā)中我們經(jīng)常會(huì)與第三方公司進(jìn)行合作,接入第三方接口,文中給出了詳細(xì)的代碼實(shí)例,需要的朋友可以參考下2023-08-08