}}总结策略模式通过定义一系列可替换的实现(策略),允许在运行时选择不同行为。在 Java 中,通过设计处理器类、枚举类型以及工厂类(如 CouponFactory)实现策略模式,可以有效提升代码的可扩展性和可维护性。不同的实现方案各有优缺点,选择时应考虑性能、代码复杂度、可扩展性以及具体业务需求。推荐方...
java程序中如何实现策略模式?
一、背景
在业务开发中,设计良好的可扩展性对于代码的维护和扩展至关重要。策略模式能帮助我们以模块化的方式处理多分支逻辑,尤其是当多个分支逻辑具有相似性时,策略模式能提供一个统一的接口来管理这些策略,提升代码的可读性和可维护性。
本文旨在通过代码案例,深入探讨策略模式在 Java 程序中的实现方式及其优缺点,旨在帮助开发者构建更加灵活、易于扩展的系统。
二、方案
为了实现策略模式,我们可以设计一系列处理器(Handler)类,每个处理器实现不同的策略行为,并通过枚举类定义策略类型。
以下为简化版本的代码示例,包括优惠券处理器的抽象类、具体处理器类、枚举类型,以及基于策略模式的实现方案:
1. **优惠券抽象类 - 处理器**
java
public abstract class CouponHandler {
public abstract CouponTypeEnum getType();
public abstract String deal();
}
2. **满减类型优惠券 - 处理器**
java
@Service
public class CashBackHandler extends CouponHandler {
@Override
public CouponTypeEnum getType() {
return CouponTypeEnum.CASH_BACK;
}
@Override
public String deal() {
System.out.println("执行:满减类优惠券处理逻辑");
return "执行结果(满减类)";
}
}
3. **折扣类型优惠券 - 处理器**
java
@Service
public class PercentOffHandler extends CouponHandler {
@Override
public CouponTypeEnum getType() {
return CouponTypeEnum.PERCENT_OFF;
}
@Override
public String deal() {
System.out.println("执行:折扣类优惠券处理逻辑");
return "执行结果(折扣类)";
}
}
4. **优惠券类型枚举**
java
@Getter
@AllArgsConstructor
public enum CouponTypeEnum {
CASH_BACK("满减"),
PERCENT_OFF("折扣");
private String desc;
}
### 方案一:多实现
java
@Component
public class CouponFactory implements InitializingBean, ApplicationContextAware {
private static final Map MAP = new ConcurrentHashMap>();
private ApplicationContext appContext;
@Override
public void afterPropertiesSet() throws Exception {
appContext.getBeansOfType(CouponHandler.class)
.values()
.forEach(handler -> MAP.putIfAbsent(handler.getType().name(), handler));
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
appContext = applicationContext;
}
public String execute(CouponTypeEnum couponTypeEnum) {
CouponHandler couponHandler = MAP.get(couponTypeEnum.name());
if (couponHandler == null) {
return null;
}
return couponHandler.deal();
}
}
### 方案二:单实现
java
@Component
public class CouponFactory implements ApplicationContextAware {
private static final Map MAP = new ConcurrentHashMap>();
@Override
public void setApplicationContext(ApplicationContext appContext) throws BeansException {
appContext.getBeansOfType(CouponHandler.class)
.values()
.forEach(handler -> MAP.putIfAbsent(handler.getType().name(), handler));
}
public String execute(CouponTypeEnum couponTypeEnum) {
CouponHandler couponHandler = MAP.get(couponTypeEnum.name());
if (couponHandler == null) {
return null;
}
return couponHandler.deal();
}
}
### 方案三:无实现、注解
java
@Component
public class CouponFactory {
@Resource
private Map map;
@PostConstruct
public void init() {
map.values().forEach(handler -> MAP.putIfAbsent(handler.getType().name(), handler));
}
public String execute(CouponTypeEnum couponTypeEnum) {
CouponHandler couponHandler = map.get(couponTypeEnum.getHandler());
if (couponHandler == null) {
// 首字母转小写(此处略)
// 获取处理器
couponHandler = map.get(String.valueOf(chars));
// 不为空则将首字母大写的key和对应的value放入map
if (couponHandler != null) {
map.putIfAbsent(couponTypeEnum.getHandler(), couponHandler);
}
}
if (couponHandler == null) {
return null;
}
return couponHandler.deal();
}
}
### 方案四:无实现、无注解
java
@Component
public class CouponFactory {
@Resource
private Map map;
public String execute(CouponTypeEnum couponTypeEnum) {
// 首字母转小写(此处略)
CouponHandler couponHandler = map.get(couponTypeEnum.getHandler());
if (couponHandler == null) {
// 获取处理器
couponHandler = map.get(String.valueOf(chars));
// 不为空则将首字母大写的key和对应的value放入map
if (couponHandler != null) {
map.putIfAbsent(couponTypeEnum.getHandler(), couponHandler);
}
}
if (couponHandler == null) {
return null;
}
return couponHandler.deal();
}
}
### 方案五:无实现、无注解、减少运算
java
@Component
public class CouponFactory {
@Resource
private Map map;
private static final ConcurrentHashMap conMap = new ConcurrentHashMap>();
public String execute(CouponTypeEnum couponTypeEnum) {
CouponHandler couponHandler = conMap.get(couponTypeEnum.getHandler());
if (couponHandler == null) {
// 首字母转小写(此处略)
couponHandler = map.get(String.valueOf(chars));
if (couponHandler != null) {
conMap.putIfAbsent(couponTypeEnum.getHandler(), couponHandler);
}
}
if (couponHandler == null) {
return null;
}
return couponHandler.deal();
}
}
### 方案六:无实现、无注解、简化
java
@Service("CashBackHandler")
public class CashBackHandler extends CouponHandler {
@Override
public String deal() {
System.out.println("执行:满减类优惠券处理逻辑");
return "执行结果(满减类)";
}
}
@Service("PercentOffHandler")
public class PercentOffHandler extends CouponHandler {
@Override
public String deal() {
System.out.println("执行:折扣类优惠券处理逻辑");
return "执行结果(折扣类)";
}
}
@Component
public class CouponFactory {
@Resource
private Map map;
public String execute(CouponTypeEnum couponTypeEnum) {
CouponHandler couponHandler = map.get(couponTypeEnum.getHandler());
if (couponHandler == null) {
// 首字母转小写(此处略)
couponHandler = map.get(String.valueOf(chars));
}
if (couponHandler == null) {
return null;
}
return couponHandler.deal();
}
}
### 总结
策略模式通过定义一系列可替换的实现(策略),允许在运行时选择不同行为。在 Java 中,通过设计处理器类、枚举类型以及工厂类(如 CouponFactory)实现策略模式,可以有效提升代码的可扩展性和可维护性。不同的实现方案各有优缺点,选择时应考虑性能、代码复杂度、可扩展性以及具体业务需求。推荐方案三或方案六,因其在实现策略模式的同时保持代码简洁、易于维护。2024-11-13