设计模式-策略模式、工厂模式应用示例
策略模式
1 业务说明:数据上报时有多个上报类,要求通过xxlJob传入的参数,决定执行哪个上报类的上报方法
2 具体实现
2.1 编写所有上报类的父接口 ReportInterface并定义report上报方法
2.2 给每个不同标准的上报需求写一个上报类(都定义成ReportInterface的子类),并实现report方法,每个实现类用@Service("XXX")定义类的别名
2.3 在xxlJob运行方法中传入类的别名,再根据别名获取对应的service实现类:
Map<String, T> beansOfType = APPLICATIONCONTEXT.getBeansOfType(ReportInterface.class);//获取ReportInterface接口的所有实现类
ReportInterface interface = beansOfType.get("XXX")//从实现类中根据类名获取对应的类(反射,多态)
工厂模式
又分简单工厂模式,工厂方法模式,抽象工厂模式,感觉工厂模式和策略模式差不多(工厂模式是根据不同参数创建不同对象,策略模式是根据不同参数执行不同业务逻辑),也是根据传参决定用哪个实现类,就是多了个factory工厂类,
工厂类根据参数获取全类名通过反射得到实现类,参数和全类名的对应关系可以存枚举类/代码写死都行
场景描述:需要实现一个日志系统,支持多种日志记录方式(如文件日志、数据库日志),且未来可能扩展新的日志类型(如云存储日志)。
简单工厂模式:
// 产品接口 interface Logger { void log(String message); } // 具体产品:文件日志 class FileLogger implements Logger { public void log(String message) { System.out.println("文件日志记录:" + message); } } // 具体产品:数据库日志 class DatabaseLogger implements Logger { public void log(String message) { System.out.println("数据库日志记录:" + message); } } // 简单工厂类 class LoggerFactory { public static Logger createLogger(String type) { if ("file".equalsIgnoreCase(type)) { return new FileLogger(); } else if ("database".equalsIgnoreCase(type)) { return new DatabaseLogger(); } throw new IllegalArgumentException("未知的日志类型"); } } // 客户端使用 public class Client { public static void main(String[] args) { Logger logger = LoggerFactory.createLogger("file"); logger.log("测试日志"); // 输出:文件日志记录:测试日志 } }
工厂方法模式:
1. 定义日志接口(抽象产品)
// 日志接口:抽象产品 public interface Logger { void log(String message); }
2. 实现具体日志类(具体产品)
// 文件日志:具体产品
public class FileLogger implements Logger {
@Override
public void log(String message) {
System.out.println("[文件日志] " + message);
}
}
// 数据库日志:具体产品
public class DatabaseLogger implements Logger {
@Override
public void log(String message) {
System.out.println("[数据库日志] " + message);
}
}
3. 定义日志工厂接口(抽象工厂)
// 日志工厂接口:抽象工厂
public interface LoggerFactory {
Logger createLogger();
}
4. 实现具体工厂类
// 文件日志工厂:具体工厂
public class FileLoggerFactory implements LoggerFactory {
@Override
public Logger createLogger() {
return new FileLogger();
}
}
// 数据库日志工厂:具体工厂
public class DatabaseLoggerFactory implements LoggerFactory {
@Override
public Logger createLogger() {
return new DatabaseLogger();
}
}
5. 客户端使用
public class Client {
public static void main(String[] args) {
// 根据配置或条件选择工厂类型
LoggerFactory factory = new FileLoggerFactory(); // 切换为 DatabaseLoggerFactory 即可使用数据库日志
// 通过工厂创建日志对象
Logger logger = factory.createLogger();//这行不用改,想换实现类改上一行就行
logger.log("用户登录成功");
}
}
两种工厂模式的区别:
简单工厂模式,一个工厂类负责所有对象的创建,新增产品需要修改工厂类逻辑;
工厂方法模式,每个具体产品对应一个具体工厂类,新增产品只需添加新工厂类,无需修改.
策略+工厂模式可以优化大量if-elseif代码,将每个elseif分支逻辑单独封装到一个类中,用策略模式决定调用哪个类,用工厂模式创建这个类.
示例场景:订单处理类型(优化 if-else)
if ("CREATE".equals(type)) { // 创建订单 } else if ("CANCEL".equals(type)) { // 取消订单 } else if ("REFUND".equals(type)) { // 退款 }
一、定义策略接口
public interface OrderStrategy { void handle(); }
二、实现不同策略类
@Component public class CreateOrderStrategy implements OrderStrategy { @Override public void handle() { System.out.println("创建订单"); } } @Component public class CancelOrderStrategy implements OrderStrategy { @Override public void handle() { System.out.println("取消订单"); } } @Component public class RefundOrderStrategy implements OrderStrategy { @Override public void handle() { System.out.println("订单退款"); } }
三、工厂类(用 Map 管理策略)
@Component public class OrderStrategyFactory implements InitializingBean { private final Map<String, OrderStrategy> strategyMap = new HashMap<>(); @Autowired private List<OrderStrategy> strategies; @Override public void afterPropertiesSet() { strategyMap.put("CREATE", getStrategy(CreateOrderStrategy.class)); strategyMap.put("CANCEL", getStrategy(CancelOrderStrategy.class)); strategyMap.put("REFUND", getStrategy(RefundOrderStrategy.class)); } private OrderStrategy getStrategy(Class<? extends OrderStrategy> clazz) { for (OrderStrategy strategy : strategies) { if (clazz.isInstance(strategy)) { return strategy; } } throw new IllegalArgumentException("未找到策略:" + clazz); } public OrderStrategy getStrategy(String type) { return strategyMap.getOrDefault(type, () -> System.out.println("未知类型")); } }
四、调用逻辑(替换 if)
@RestController public class OrderController { @Autowired private OrderStrategyFactory strategyFactory; @GetMapping("/order") public void handle(@RequestParam String type) { OrderStrategy strategy = strategyFactory.getStrategy(type); strategy.handle(); } }
代理模式
代理类和被代理的类实现共同的接口,代理类里有被代理类这个成员变量,代理类的方法实现靠调用被代理类的方法,方法里可以再加点额外代码。
浙公网安备 33010602011771号