项目中原来策略模式这么玩才有意思😁😁😁

策略模式工作中应该怎么玩

01策略模式简介

策略模式(Strategy Pattern):类似于"方案库"。提前准备好不同的解决方案,并使它们像插件一样,随时被选用和替换,动态实现业务需要。

策略模式有三个成员

  • Strategy:声明的策略接口,供客户端调用。比如你要去远方旅游,需要选择一种交通方式,这个出行的交通方式可以理解为是抽象出来的方法。
  • Concrete Strategy: 具体的策略算法实现,如坐火车、飞机、汽车等等交通方式。
  • Context:上下文,持有策略的引用。

02基础代码实现

以用户交通出行为例:

交通工具抽象接口

java 复制代码
/**
 * 策略抽象接口 - 交通工具
 */
public interface TransportationStrategy {
    /**
     * 交通方式
     */
    void transport();
}

具体交通工具实现

java 复制代码
/**
 * 2. 具体策略类 - 飞机
 */
public class AirplaneStrategy implements TransportationStrategy {
    @Override
    public void transport() {
        System.out.println("✈️ 乘坐飞机");
    }
}

/**
 * 2. 具体策略类 - 火车
 */
public class TrainStrategy implements TransportationStrategy {
    @Override
    public void transport() {
        System.out.println("🚄 乘坐火车");
    }
}

/**
 * 2. 具体策略类 - 汽车
 */
public class CarStrategy implements TransportationStrategy {
    @Override
    public void transport() {
        System.out.println("🚗 驾驶汽车");
    }
}

策略上下文:

java 复制代码
/**
 * 策略上下文
 */
public class TransportContext {

    private TransportationStrategy strategy;

    /**
     * 通过构造函数,初始化strategy对象
     */
    public TransportContext(TransportationStrategy strategy) {
        this.strategy = strategy;
    }

    /**
     * 执行具体的策略方法
     */
    public void doTransport() {
        strategy.transport();
    }

    /**
     * 手动变更策略
     */
    public void setStrategy(TransportationStrategy strategy) {
        this.strategy = strategy;
    }
}

新建一个main方法执行下:

java 复制代码
public static void main(String[] args) {
    TransportContext context = new TransportContext(new CarStrategy());
    context.doTransport();

    context.setStrategy(new AirplaneStrategy());
    context.doTransport();

    context.setStrategy(new TrainStrategy());
    context.doTransport();
}

执行结果:

shell 复制代码
🚗 驾驶汽车
✈️ 乘坐飞机
🚄 乘坐火车

03 项目实战

以上是简化版的策略代码,但在项目中我们一般将具体的对象交由spring容器来管理使用。借助工厂 + 策略来完成业务功能研发。

将业务对象进行改造,首先新建一个枚举类,用于标识不同的出行方式:

java 复制代码
/**
 * 交通方式枚举类
 */
@Getter
public enum TransportEnum {
    /**
     * 飞机
     */
    AIRPLANE,
    /**
     * 汽车
     */
    CAR,
    /**
     * 火车
     */
    TRAIN,
}

其次,我们在抽象接口中新增交通方式类型方法,方便各个交通方式声明自己所属的类型:

java 复制代码
/**
 * 策略抽象接口 - 交通工具
 */
public interface TransportationStrategy {
    /**
     * 交通方式
     */
    void transport();
    
    /**
     * 交通类型
     */
    TransportEnum getType();
}

对应的具体实现类我们也需要调整下

  • 声明自己的类型
  • 交由spring容器管理
typescript 复制代码
/**
 * 2. 具体策略类 - 飞机
 */
@Component
public class AirplaneStrategy implements TransportationStrategy {
    @Override
    public void transport() {
        System.out.println("✈️ 乘坐飞机");
    }

    @Override
    public TransportEnum getType() {
        return TransportEnum.AIRPLANE;
    }
}

/**
 * 2. 具体策略类 - 火车
 */
@Component
public class TrainStrategy implements TransportationStrategy {
    @Override
    public void transport() {
        System.out.println("🚄 乘坐火车");
    }

    @Override
    public TransportEnum getType() {
        return TransportEnum.TRAIN;
    }
}

/**
 * 2. 具体策略类 - 汽车
 */
@Component
public class CarStrategy implements TransportationStrategy {
    @Override
    public void transport() {
        System.out.println("🚗 驾驶汽车");
    }

    @Override
    public TransportEnum getType() {
        return TransportEnum.CAR;
    }
}

具体的工厂实现:

java 复制代码
/**
 * 交通方式工厂
 */
@Component
public class TransportationFactory implements InitializingBean {

    @Resource
    private ApplicationContext applicationContext;

    /**
     * 交通方式策略映射
     */
    private static final Map<TransportEnum, TransportationStrategy> TRANSPORT_MAP = new ConcurrentHashMap<>();

    /**
     * 获取交通方式策略
     *
     * @param transportEnum 交通方式枚举
     * @return 交通方式策略
     */
    public TransportationStrategy getTransportation(TransportEnum transportEnum) {
        return TRANSPORT_MAP.get(transportEnum);
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        applicationContext.getBeansOfType(TransportationStrategy.class)
                .values()
                .forEach(strategy -> {
                    TRANSPORT_MAP.put(strategy.getType(), strategy);
                });
    }
}

以上,我们的spring容器化改造就完成啦,接下来搞个简单的测试类,我们试一下吧 😊😊😊

less 复制代码
@RestController
@RequestMapping("/strategy")
public class TestStrategyController {

    @Resource
    private TransportationFactory factory;

    @GetMapping("/test")
    public void test() {
        factory.getTransportation(TransportEnum.AIRPLANE).transport();
        factory.getTransportation(TransportEnum.TRAIN).transport();
        factory.getTransportation(TransportEnum.CAR).transport();
    }
}

控制台输出:

shell 复制代码
✈️ 乘坐飞机
🚄 乘坐火车
🚗 驾驶汽车

好了,以上就是本期的内容,希望大家能喜欢,新人创作,感谢支持 !!!

相关推荐
在未来等你6 小时前
AI Agent设计模式 Day 19:Feedback-Loop模式:反馈循环与自我优化
设计模式·llm·react·ai agent·plan-and-execute
兵bing11 小时前
设计模式-访问者模式
设计模式·访问者模式
python零基础入门小白11 小时前
【万字长文】大模型应用开发:意图路由与查询重写设计模式(从入门到精通)
java·开发语言·设计模式·语言模型·架构·大模型应用开发·大模型学习
MC丶科12 小时前
Java设计模式漫画英雄宇宙-工厂模式 —Factory博士的“超级英雄制造机”!
java·设计模式·漫画
明洞日记12 小时前
【设计模式手册013】命令模式 - 请求封装的优雅之道
java·设计模式·命令模式
ada0_ada113 小时前
行为型模式:②命令模式(Command Pattern)
设计模式
o0向阳而生0o14 小时前
113、23种设计模式之中介者模式(21/23)
设计模式·中介者模式
心语星光14 小时前
23种经典设计模式
设计模式
ACE19851 天前
AI Agent 设计模式深度解析:提示链(Prompt Chaining)模式
人工智能·设计模式·prompt
明洞日记1 天前
【设计模式手册012】责任链模式 - 请求处理的流水线艺术
java·设计模式·责任链模式