Java設(shè)計(jì)模式中的策略(Strategy)模式解讀
Java的策略模式
策略(Strategy)模式:分離算法,選擇實(shí)現(xiàn) 比如對象的某個(gè)行為,在不同場景有不同實(shí)現(xiàn)方式,可以將這些行為的具體實(shí)現(xiàn)定義為一組策略,每個(gè)實(shí)現(xiàn)類實(shí)現(xiàn)一種策略,在不同場景使用不同的實(shí)現(xiàn),并且可以自由切換策略,但太多的策略會導(dǎo)致大量代碼
- 優(yōu)點(diǎn):
- 不用太多if else
- 代碼優(yōu)雅、簡單
- 符合開閉原則,擴(kuò)展性好、便于維護(hù)
- 缺點(diǎn):
- 策略如果很多的話,會造成策略類膨脹
- 使用者必須清楚所有的策略類及其用途
如:電商活動打折,普通會員9折,黃金會員8折,鉆石會員7折
1.定義一個(gè)Strategy接口,只有打折方法
2.增加3個(gè)打折類,對應(yīng)9折、8折、7折
3.客戶端根據(jù)會員類型,獲取具體的策略算法實(shí)現(xiàn)類,再執(zhí)行打折方法

策略模式與Spring結(jié)合
/**
* 打折策略枚舉
*/
public enum ActivityStrategyEnum {
MEMBER(1, "普通會員"),
GOLD_MEMBER(2, "黃金會員"),
DIAMOND_MEMBER(3, "鉆石會員"),
;
private int code;
private String name;
ActivityStrategyEnum (int code, String name) {
this.code = code;
this.name = name;
}
/**
* 通過code匹配對應(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) {
//普通會員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) {
//黃金會員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) {
//鉆石會員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,可以理解為策略的注冊中心
*/
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("初始化策略模式的鍵值對 code =" + strategyService.getCode() + " ,value=" + strategyService);
}
}
/**
* 注入applicationContext
*
* @param applicationContext
* @throws BeansException
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
/**
* 通過枚舉code獲取對應(yīng)對更新服務(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 {
//會員類型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)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot Application的exclude不生效問題及排查
這篇文章主要介紹了SpringBoot Application的exclude不生效問題及排查,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-11-11
java工具類static靜態(tài)方法讀取yml配置過程
文章介紹了在工具類中獲取YAML配置時(shí)遇到的問題,由于變量是靜態(tài)的,而Spring加載靜態(tài)方法比IOC容器早,導(dǎo)致無法直接使用@Value注解讀取YAML配置,從而讀取結(jié)果為null2024-11-11
springboot整合Sa-Token實(shí)現(xiàn)登錄認(rèn)證和權(quán)限校驗(yàn)的詳細(xì)流程
Sa-Token是國產(chǎn)輕量級權(quán)限認(rèn)證框架,支持登錄、權(quán)限校驗(yàn)、單點(diǎn)登錄及分布式會話,配置簡便且API設(shè)計(jì)直觀,相比Spring Security更易上手,適合快速實(shí)現(xiàn)安全功能,助力國產(chǎn)開源發(fā)展,感興趣的朋友跟隨小編一起看看吧2025-09-09
使用spring boot 整合kafka,延遲啟動消費(fèi)者
這篇文章主要介紹了使用spring boot 整合kafka,延遲啟動消費(fèi)者的操作,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-08-08
java:?無效的目標(biāo)發(fā)行版:?20問題解決辦法
這篇文章主要給大家介紹了關(guān)于java:?無效的目標(biāo)發(fā)行版:?20問題的解決辦法,出現(xiàn)這個(gè)問題大多數(shù)是因?yàn)樽约喊惭b的jdk版本和你在運(yùn)行項(xiàng)目時(shí)的所選的jdk版本不一致所導(dǎo)致的,需要的朋友可以參考下2024-03-03

