Java设计模式-策略模式-增强

原来的简单策略模式

Java设计模式-策略模式-基于Spring实现:https://www.cnblogs.com/kakarotto-chen/p/17761621.html

一、工厂模式分开处理不同的策略模式(最终推荐)

  • 问题:以后把所有策略类型都写在这个工厂【原来的策略实现】,有二三十种
  • 不推荐!强烈反对!

为什么不推荐:

❌ 问题1:上帝类(God Class)反模式

  • 一个工厂类管理所有策略 → 违反了单一职责原则
  • 文件会变得极其庞大(几千行代码)
  • 任何修改都要动这个文件,风险巨大

❌ 问题2:编译耦合

  • 改一个策略,整个工厂和所有依赖它的服务都要重新编译
  • 几十个策略在一个文件里,编译时间会很长

❌ 问题3:团队协作困难

  • 多人同时修改同一个文件,冲突不断
  • 代码审查困难,难以理解整体逻辑

❌ 问题4:维护噩梦

  • 找特定策略的方法就像大海捞针
  • 测试困难,一个工厂的测试用例会极其庞大
  • 部署风险高,一个小改动可能影响所有策略

二、推荐方案:

不一定! 策略数量多,要按业务领域拆分,而不是简单地"一个策略一个工厂"。

✅ 按业务(推荐)

策略工厂/
├── 订单策略组(3个相关策略)
│   ├── OrderStrategyFactory.java
│   ├── IOrderCreateStrategy.java
│   ├── IOrderCancelStrategy.java
│   └── IOrderRefundStrategy.java
├── 支付策略组(4个相关策略)
│   ├── PaymentStrategyFactory.java
│   ├── IPaymentStrategy.java
│   ├── IRefundStrategy.java
│   ├── IQueryStrategy.java
│   └── INotifyStrategy.java
├── 风控策略组(3个相关策略)
│   ├── RiskStrategyFactory.java
│   ├── IRiskCheckStrategy.java
│   ├── IRiskControlStrategy.java
│   └── IRiskAlertStrategy.java
└── 通知策略组(3个相关策略)
    ├── NotifyStrategyFactory.java
    ├── ISmsStrategy.java
    ├── IEmailStrategy.java
    └── IPushStrategy.java

❌ 不要这样拆(太碎)

策略工厂/
├── OrderCreateStrategyFactory.java   ❌ 太碎
├── OrderCancelStrategyFactory.java   ❌ 太碎
├── WechatPaymentStrategyFactory.java ❌ 太碎
├── AlipayStrategyFactory.java        ❌ 太碎
├── SmsStrategyFactory.java           ❌ 太碎
└── EmailStrategyFactory.java         ❌ 太碎

分组标准:

  1. 高内聚:同一业务领域的策略放一起
  2. 常一起使用:经常同时调用的策略放一起
  3. 相同变更频率:同时修改的策略放一起
  4. 团队分工:不同团队负责的策略分开

经验数据:

  • 每个工厂管理 3-5个 相关策略最合适

  • 单个工厂超过 300行代码 就要考虑拆分

  • 一个策略接口对应 1个工厂(不是1个实现对应1个工厂)

  • 1-3种策略:可以放在一个工厂

  • 4-8种策略:考虑按业务领域拆分

  • 8种以上策略:必须拆分,每个工厂最多管3-5种

你的架构决策会影响团队未来几年的开发效率,请谨慎选择!

三、最终实现

  • 项目结构
    image

  • 策略接口

    • getSupportedType也可以改成返回数组,支持多种类型指向同一个策略
package com.cc.ds.strategy;

import com.cc.ds.constant.Cons;

/**
 * <p>工作流的策略</p>
 *
 * @author cc
 * @since 2025/12/25
 */
public interface IWorkFlowStrategy {

    /**
     * 获取支持的业务类型
     * @return 业务类型
     */
    Integer getSupportedType();

    default String getStrategyKey() {
        // 用类型作为key,避免依赖外部枚举
        return Cons.WORK_FLOW_ + getSupportedType();
    }

    /** 第一个策略方法
     * @since 2025/12/25
     * @author cc
     **/
    void create();

}

  • 策略工厂
package com.cc.ds.strategy.workflow;

import com.cc.ds.constant.Cons;
import com.cc.ds.strategy.IWorkFlowStrategy;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>WorkFlow策略工厂</p>
 *
 * @author cc
 * @since 2025/12/25
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class WorkFlowStrategyFactory {

    /**
     * 批量注入实现了 IWorkFlowStrategy 的Bean
     */
    private final Map<String, IWorkFlowStrategy> strategies;

    @Autowired
    public WorkFlowStrategyFactory(List<IWorkFlowStrategy> strategies) {
        this.strategies = strategies.stream()
                .collect(Collectors.toMap(
                        IWorkFlowStrategy::getStrategyKey,
                        Function.identity()
                ));
    }

    /**
     * <p>根据类型获取不同的工作流策略<p>
     * @param zyBusiness 业务类型
     * @return {@link IWorkFlowStrategy}
     * @since 2025/12/25
     * @author cc
     **/
    public IWorkFlowStrategy getStrategy(Integer zyBusiness) {
        String key = Cons.WORK_FLOW_ + zyBusiness;
        IWorkFlowStrategy strategy = strategies.get(key);
        if (Objects.isNull(strategy)) {
            throw new IllegalArgumentException(
                    String.format("策略不存在: businessType=%s, availableKeys=%s",
                    zyBusiness, strategies.keySet()));
        }
        log.debug("获取工作流策略: {} -> {}", key, strategy.getClass().getSimpleName());
        return strategy;
    }
}
  • 策略实现1:还有一个一样的
package com.cc.ds.strategy.workflow;

import com.cc.ds.strategy.IWorkFlowStrategy;
import org.springframework.stereotype.Component;

/**
 * <p>入湖工作流</p>
 *
 * @author cc
 * @since 2025/12/25
 */
@Component
public class LakeWorkFlowStrategy implements IWorkFlowStrategy {

    @Override
    public Integer getSupportedType() {
        return 1;
    }

    @Override
    public void create() {
        System.out.println("lake");
    }
}
  • 策略实现2:还有一个一样的
package com.cc.ds.strategy.workflow;

import com.cc.ds.dolphin.dto.WorkflowCreateDto;
import com.cc.ds.enums.BusinessType;
import com.cc.ds.strategy.IWorkFlowStrategy;
import org.springframework.stereotype.Component;

/**
 * <p>标准层工作流</p>
 *
 * @author cc
 * @since 2025/12/25
 */
@Component
public class StandardWorkFlowStrategy implements IWorkFlowStrategy {

    @Override
    public Integer getSupportedType() {
        return 2;
    }

    @Override
    public void create(WorkflowCreateDto dto) {
        System.out.println("Standard");
    }

}
  • 使用
    @Autowired
    WorkFlowStrategyFactory workFlowStrategyFactory;

    @Test
    public void strategy()throws Exception{
        IWorkFlowStrategy workFlowStrategy = workFlowStrategyFactory.getStrategy(1);
        System.out.println(workFlowStrategy);

        workFlowStrategy.create();
    }

image

image

posted on 2025-12-25 15:57  C_C_菜园  阅读(5)  评论(0)    收藏  举报

导航