Java設(shè)計模式中的策略(Strategy)模式解讀
Java的策略模式
策略(Strategy)模式:分離算法,選擇實現(xiàn) 比如對象的某個行為,在不同場景有不同實現(xiàn)方式,可以將這些行為的具體實現(xiàn)定義為一組策略,每個實現(xiàn)類實現(xiàn)一種策略,在不同場景使用不同的實現(xiàn),并且可以自由切換策略,但太多的策略會導(dǎo)致大量代碼
- 優(yōu)點:
- 不用太多if else
- 代碼優(yōu)雅、簡單
- 符合開閉原則,擴(kuò)展性好、便于維護(hù)
- 缺點:
- 策略如果很多的話,會造成策略類膨脹
- 使用者必須清楚所有的策略類及其用途
如:電商活動打折,普通會員9折,黃金會員8折,鉆石會員7折
1.定義一個Strategy接口,只有打折方法
2.增加3個打折類,對應(yīng)9折、8折、7折
3.客戶端根據(jù)會員類型,獲取具體的策略算法實現(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è)計模式中的策略(Strategy)模式解讀的文章就介紹到這了,更多相關(guān)Java的策略模式內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
IntelliJ IDEA 部署 Web 項目,看這一篇夠了!
這篇文章主要介紹了IntelliJ IDEA 部署 Web 項目的圖文教程,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-05-05
Spring Cloud 覆寫遠(yuǎn)端的配置屬性實例詳解
這篇文章主要介紹了Spring Cloud 覆寫遠(yuǎn)端的配置屬性的相關(guān)知識,非常不錯,具有參考借鑒價值,需要的朋友可以參考下2018-01-01
Java啟用Azure Linux虛擬機(jī)診斷設(shè)置
這篇文章主要介紹了Java啟用Azure Linux虛擬機(jī)診斷設(shè)置,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-05-05
Java調(diào)用第三方http接口的四種方式總結(jié)
這篇文章主要給大家介紹了關(guān)于Java調(diào)用第三方http接口的四種方式,在實際開發(fā)中我們經(jīng)常會與第三方公司進(jìn)行合作,接入第三方接口,文中給出了詳細(xì)的代碼實例,需要的朋友可以參考下2023-08-08

