java程序中如何实现策略模式?

}}总结策略模式通过定义一系列可替换的实现(策略),允许在运行时选择不同行为。在 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
mengvlog 阅读 9 次 更新于 2025-06-20 01:17:45 我来答关注问题0
  • 在业务开发中,设计良好的可扩展性对于代码的维护和扩展至关重要。策略模式能帮助我们以模块化的方式处理多分支逻辑,尤其是当多个分支逻辑具有相似性时,策略模式能提供一个统一的接口来管理这些策略,提升代码的可读性和可维护性。本文旨在通过代码案例,深入探讨策略模式在 Java 程序中的实现方式及其优缺点...

  •  翡希信息咨询 用Java注解去代替if-else语句的技巧

    在应用程序启动时,通过扫描注解或使用其他机制将这些策略类注册到一个映射中。键通常是注解中的值,值是相应的策略实现类实例。在需要执行策略的地方,根据当前策略从映射中获取相应的策略实现类,并调用其方法。利用Spring框架:如果使用Spring框架,可以将策略类作为Spring Bean注入,并通过Spring的依赖注入...

  • 理解注解的本质和动态代理机制后,我们能够灵活地利用注解实现策略模式,并解决在应用中遇到的复杂问题。例如,将map的键类型从订单来源字符串转换为OrderHandlerType注解,可以实现更精细的策略选择逻辑,同时保持代码的高扩展性和灵活性。通过这种方式,无论业务如何发展,OrderService的核心逻辑保持不变,只需...

  •  阿暄生活 java 策略模式和工厂模式 java策略模式和工厂模式

    结构:策略模式通常由策略接口、具体策略类以及上下文类组成。策略接口声明了所有支持的算法,具体策略类实现了这些算法,上下文类持有一个策略对象,在运行时通过该对象调用具体的算法。应用场景:当存在多个算法,且这些算法在运行时可以互换时,可以使用策略模式。例如,搜索引擎中的排序算法,可以根据用户需求...

  •  翡希信息咨询 SPI 机制,「可插拔」的奥义所在!

    在Java中,SPI接口通常结合配置文件进行使用,通过读取配置文件实现组件的可插拔特性。广泛应用:SPI机制不仅在JDK中实现,还广泛应用于Spring、Dubbo等框架中,使得第三方服务模块与业务代码解耦,进一步简化了配置与实现的管理。策略模式的实现:SPI机制常用于策略模式的实现,通过接口定义一系列算法,将每一个...

檬味博客在线解答立即免费咨询

Java相关话题

Copyright © 2023 WWW.MENGVLOG.COM - 檬味博客
返回顶部