设计模式之策略模式

定义

策略模式(Strategy Pattern)是一种行为设计模式,它定义了一系列算法,将每个算法封装起来,使它们可以互换。策略模式使得算法可以在不影响客户端的情况下发生变化。此模式让算法独立于使用它的客户而独立变化。

使用场景

策略模式适用于以下几种情况:

  1. 多个相关类仅在行为上有所不同。策略模式可以将这些行为封装到独立的策略类中,使得它们可以互换。
  2. 需要使用不同的变体(算法)。例如,对于某些操作需要有不同的实现方式,策略模式可以让这些实现方式独立出来,并且可以方便地进行替换。
  3. 算法使用客户不应知道的数据。策略模式可以将算法的实现细节隐藏在策略类中。
  4. 一个类定义了多种行为,并且这些行为在这个类的操作中以多重条件语句的形式出现。策略模式可以将这些行为移到策略类中,使得条件判断语句消失。

主要角色

策略模式包含三个主要角色:

  1. 策略接口(Strategy Interface):定义了一个算法族,所有的具体策略类都要实现这个接口。
  2. 具体策略类(Concrete Strategy):实现了策略接口中的具体算法。
  3. 上下文类(Context):持有一个策略类的引用,并且可以动态地更换策略。

类图

策略模式类图

示例代码

以下是策略模式的一个简单实现:

抽象策略角色

// 抽象策略角色
public interface Strategy {
    // 策略模式的运算法则
    void doSomething();
}

具体策略角色

// 具体策略角色
public class ConcreteStrategy1 implements Strategy {
    @Override
    public void doSomething() {
        System.out.println("具体策略1的运算法则...");
    }
}
// 具体策略角色
public class ConcreteStrategy2 implements Strategy {
    @Override
    public void doSomething() {
        System.out.println("具体策略2的运算法则...");
    }
}

封装角色

// 封装角色
public class Context {
    // 抽象策略
    private Strategy strategy;

    // 构造函数设置具体策略
    public Context(Strategy strategy) {
        this.strategy = strategy;
    }

    // 封装后的策略方法
    public void doAnything() {
        this.strategy.doSomething();
    }
}

客户端代码

public class Client {
    public static void main(String[] args) {
        // 拿到一个具体的策略
        Strategy strategy = new ConcreteStrategy1();
        // 创建上下文对象
        Context context = new Context(strategy);
        // 执行封装后的方法
        context.doAnything();
    }
}

使用Spring实现策略模式+工厂模式

在实际开发中,使用Spring可以更方便地管理策略模式。我们可以结合工厂模式来动态获取具体的策略类。

定义策略接口

public interface Strategy {
    // 策略模式的运算法则
    void doSomething();
}

具体策略类

@Component("concreteStrategy1")
public class ConcreteStrategy1 implements Strategy {
    @Override
    public void doSomething() {
        System.out.println("具体策略1的运算法则...");
    }
}
```java
@Component("concreteStrategy2")
public class ConcreteStrategy2 implements Strategy {
    @Override
    public void doSomething() {
        System.out.println("具体策略2的运算法则...");
    }
}
@Component("defaultStrategy")
public class DefaultStrategy implements Strategy {
    @Override
    public void doSomething() {
        System.out.println("默认策略的运算法则...");
    }
}

策略工厂类

@Component
public class StrategyFactory {
    // Spring会自动将Strategy接口的实现类注入到这个Map中,key为bean id,value值则为对应的策略实现类
    @Autowired
    private Map<String, Strategy> strategyMap;

    public Strategy getStrategy(String strategyName) {
        return strategyMap.get(strategyName);
    }
}

测试类

@SpringBootTest
class SpringbootDemoApplicationTests {

    @Autowired
    private StrategyFactory strategyFactory;

    @Test
    public void test() {
        strategyFactory.getStrategy("concreteStrategy1").doSomething();
        strategyFactory.getStrategy("concreteStrategy2").doSomething();
    }
}

工作中的实际应用场景

在工作中,策略模式常被用来处理各种需要灵活应对变化的业务逻辑。例如,订阅视频平台的事件处理(异常振动、蒸汽泄露、未带安全帽等)就是一个典型的应用场景。每个类型的事件可以对应一个处理类(策略类),这样在后续如果需要订阅其他事件时,只需增加新的策略类即可,不需要修改原有的代码,符合开闭原则。

具体实现

假设我们需要处理多个视频平台事件,每个事件类型需要一个处理类,我们可以定义如下策略接口和具体策略类:

定义事件处理策略接口
public interface EventHandler {
    void handleEvent();
}
具体事件处理策略类
@Component("vibrationEventHandler")
public class VibrationEventHandler implements EventHandler {
    @Override
    public void handleEvent() {
        System.out.println("处理振动事件...");
    }
}
@Component("steamLeakEventHandler")
public class SteamLeakEventHandler implements EventHandler {
    @Override
    public void handleEvent() {
        System.out.println("处理蒸汽泄露事件...");
    }
}
@Component("noHelmetEventHandler")
public class NoHelmetEventHandler implements EventHandler {
    @Override
    public void handleEvent() {
        System.out.println("处理未带安全帽事件...");
    }
}
事件处理策略工厂类
@Component
public class EventHandlerFactory {
    @Autowired
    private Map<String, EventHandler> eventHandlerMap;

    public EventHandler getEventHandler(String eventType) {
        return eventHandlerMap.get(eventType);
    }
}
客户端代码
@SpringBootTest
class EventHandlingTests {

    @Autowired
    private EventHandlerFactory eventHandlerFactory;

    @Test
    public void testEventHandling() {
        eventHandlerFactory.getEventHandler("vibrationEventHandler").handleEvent();
        eventHandlerFactory.getEventHandler("steamLeakEventHandler").handleEvent();
        eventHandlerFactory.getEventHandler("noHelmetEventHandler").handleEvent();
    }
}

总结

策略模式是一种非常实用的设计模式,可以有效地应对多变的需求和场景。结合Spring等框架,策略模式的实现变得更加简洁和易于维护。在实际开发中,策略模式可以帮助我们更好地管理算法和业务逻辑,使系统具有更好的扩展性和维护性。

通过本文,我们了解了策略模式的定义、使用场景、主要角色及其实现方式,并结合实际工作中的场景进行了详细讲解,希望能够帮助开发者在实际项目中灵活运用策略模式,提高代码的可维护性和扩展性。

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值