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);
 
    }
}
相关推荐
cooldream200912 小时前
深入理解MVP架构:让UI层与业务逻辑完美分离的设计模式
ui·设计模式·架构·系统架构师
摘星编程14 小时前
并发设计模式实战系列(3):工作队列
设计模式·并发编程
Pasregret15 小时前
访问者模式:分离数据结构与操作的设计模式
数据结构·设计模式·访问者模式
Aniugel17 小时前
JavaScript高级面试题
javascript·设计模式·面试
不当菜虚困18 小时前
JAVA设计模式——(四)门面模式
java·开发语言·设计模式
Niuguangshuo18 小时前
Python设计模式:MVC模式
python·设计模式·mvc
Lei活在当下18 小时前
【现代 Android APP 架构】01. APP 架构综述
android·设计模式·架构
前端大白话18 小时前
震惊!90%前端工程师都踩过的坑!computed属性vs methods到底该怎么选?一文揭秘高效开发密码
前端·vue.js·设计模式
前端大白话18 小时前
前端必看!figure标签在响应式图片排版中的王炸操作,grid/flex布局实战指南
前端·设计模式·html
難釋懷18 小时前
Shell脚本-while循环语法结构
linux·运维·服务器·bash