17、设计模式之策略模式(Strategy)

一、什么是策略模式

策略模式属于行为型设计模式。定义了一系列算法,并将这些算法封装到一个类中,使得他们可以相互替换。这样,我们可以在改变某个对象使用的算法的情况下,选择一个合适的算法来处理特定的任务,主要解决多重if-else的判断逻辑。

二、角色组成

环境类(Context):环境类是策略模式的核心类,它持有一个策略对象的引用,并在需要时调用策略对象的方法。

抽象策略类(Strategy):定义了策略方法,这些方法表示不同的策略行为。 具体策略类(Concrete

Strategy):抽象策略类的实现,它实现了抽象策略类中定义的策略方法,并提供了具体的算法实现。不同的具体策略类具有不同的实现算法,它们之间可以相互替换,使得环境类在运行时可以动态地改变策略。

三、优缺点

优点:

算法可以自由切换。

避免使用多重条件判断。

扩展性良好

缺点:

策略类会增多。

所有策略类都需要对外暴露。

判断逻辑在客户端,需求改变时,要更改客户端的程序。

四、应用场景

4.1 生活场景

手机开锁方式:密码、指纹、面部识别

出游的交通方式:自驾、汽车、火车、飞机、高铁,每一种方式都是一个策略。

开通csdn会员的方式:月卡、年卡、超级年卡、两年卡、连续包月。

4.2 java场景

Spring Security中的认证和授权策略:在Spring Security中,可以使用不同的策略来定义认证和授权的行为,例如PasswordAuthentication(密码验证)、RememberMeAuthentication(记住我功能验证)、RoleBasedAuthorization(基于角色的授权)等。通过配置不同的策略,可以灵活地适应不同的安全需求。

Comparator接口:在使用排序算法时,可以通过实现Comparator接口来定义不同的比较策略,从而可以根据需求对对象进行自定义排序。

线程池(ThreadPoolExecutor):在ThreadPoolExecutor中,可以通过设定不同的拒绝策略(RejectedExecutionHandler)来处理无法提交的新任务。拒绝策略可以根据系统的需求选择不同的处理方式,如抛出异常、丢弃任务等。

五、代码实现

下面以视频平台为例,解释一下策略模式。

环境类(Context):VideoContext

抽象策略类(Strategy):VideoStrategy

具体策略类(Concrete Strategy):DyVideoStrategy、WxVideoStrategy、KsVideoStrategy

5.0、UML类图

5.1、VideoContext------环境类(Context)

java 复制代码
/**
 *
 * 1.策略环境类(Context)
 * 在初始化VideoContext对象时,将所有策略实现类塞进Map中,
 * key为视频类型(dy、ks、wx) value为对应的视频实现类
 * 通过getVideoStrategy方法,根据videoType从map中渠道对应的视频策略
 * 从而隐藏了策略的具体实现逻辑。这种方式可以遵循开闭原则,因为在新增视频类型时,只需要增加对应的实现类
 */
@Component
public class VideoContext {
 
    private static final Map<String, VideoStrategy> videoMap = new HashMap<>();
 
    /**
     * 对象初始化时,将所有策略实现类加入到map中
     * @param videoStrategies
     */
    public VideoContext(List<VideoStrategy> videoStrategies) {
        videoStrategies.forEach(strategy -> videoMap.put(strategy.getVideoType(), strategy));
    }
 
    /**
     * 根据videoType获取对应的策略实现类
     * @param videoType
     * @return
     */
    public VideoStrategy getVideoStrategy(String videoType){
        VideoStrategy videoStrategy = videoMap.get(videoType);
        if (videoStrategy==null) {
            throw new RuntimeException("videoType inValid!");
        }
        return videoStrategy;
    }
}

5.2、VideoStrategy------抽象策略类(Strategy)

java 复制代码
/**
 *
 * 2.抽象策略类(Strategy)
 */
public interface VideoStrategy {
    //刷视频
    String brushVideo();
    //视频类型
    String getVideoType();
}

5.3、具体策略类(Concrete Strategy)

java 复制代码
/**
 *
 *  3.具体策略类(Concrete Strategy):微信
 */
@Component
public class WxVideoStrategy implements VideoStrategy{
    @Override
    public String brushVideo() {
        return "我在刷微信视频号";
    }
 
    @Override
    public String getVideoType() {
        return "wx";
    }
}
/**
 * 
 *  3.具体策略类(Concrete Strategy):快手
 */
@Component
public class KsVideoStrategy implements VideoStrategy{
    @Override
    public String brushVideo() {
        return "我在刷快手";
    }
 
    @Override
    public String getVideoType() {
        return "ks";
    }
}
/**
 *
 * 3.具体策略类(Concrete Strategy):抖音
 */
@Component
public class DyVideoStrategy implements VideoStrategy{
    @Override
    public String brushVideo() {
        return "我在刷抖音";
    }
 
    @Override
    public String getVideoType() {
        return "dy";
    }
}

5.4、TestStrategy

java 复制代码
/**
 *
 * 策略模式测试类
 */
@SpringBootTest
public class TestStrategy {
 
    @Autowired
    private VideoContext videoContext;
 
    @Test
    void testStrategy(){
        //策略模式
        VideoStrategy video1 = videoContext.getVideoStrategy("dy");
        String v1 = video1.brushVideo();
        System.out.println("v1 : " + v1);
        VideoStrategy video2 = videoContext.getVideoStrategy("ks");
        String v2 = video2.brushVideo();
        System.out.println("v2 : " + v2);
        VideoStrategy video3 = videoContext.getVideoStrategy("wx");
        String v3 = video3.brushVideo();
        System.out.println("v3 : " + v3);
 
    }
}
相关推荐
geovindu17 小时前
rust: Simple Factory Pattern(续)
后端·设计模式·rust·简单工厂模式·创建型模式
喜欢coding的谢同学18 小时前
Go语言常用设计模式基础和实践案例介绍
开发语言·设计模式·golang
sarasuki1 天前
Agent 的记忆有几种?你的名字是?
人工智能·设计模式·agent
geovindu2 天前
rust: Flyweight Pattern
开发语言·后端·设计模式·rust·享元模式·结构型模式
龙腾-虎跃2 天前
Linux 趣味实战|纯 Bash Shell 脚本实现俄罗斯方块终端小游戏(完整源码资源)
linux·运维·bash
沫璃染墨2 天前
《Linux工程实践篇(一):认识设计模式——从日志系统看策略模式》
linux·c++·安全·设计模式·策略模式
十六宿舍2 天前
【软件设计模式-第一课:基础知识了解】
设计模式·架构·面向对象·软件架构
AIex-YH2 天前
工艺降污:把环保账前移到发酵罐——源头减量清单
制造·策略模式
geovindu3 天前
rust: Facade Pattern
开发语言·后端·设计模式·rust·外观模式
AIex-YH3 天前
资源化利用全景:饲料化/肥料化/能源化/材料化的能走与不能走
制造·策略模式