设计模式-策略模式、工厂模式应用示例

策略模式

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();
    }
}

 

代理模式

代理类和被代理的类实现共同的接口,代理类里有被代理类这个成员变量,代理类的方法实现靠调用被代理类的方法,方法里可以再加点额外代码。

 

 
 
 
 
posted @ 2024-06-24 17:22  杨吃羊  阅读(24)  评论(0)    收藏  举报