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);
 
    }
}
相关推荐
刷帅耍帅17 分钟前
设计模式-迭代器模式
设计模式·迭代器模式
liu_chunhai37 分钟前
设计模式(3)builder
java·开发语言·设计模式
刷帅耍帅40 分钟前
设计模式-策略模式
设计模式·策略模式
刷帅耍帅5 小时前
设计模式-享元模式
设计模式·享元模式
刷帅耍帅5 小时前
设计模式-模版方法模式
设计模式
醉颜凉7 小时前
银河麒麟桌面操作系统修改默认Shell为Bash
运维·服务器·开发语言·bash·kylin·国产化·银河麒麟操作系统
刷帅耍帅7 小时前
设计模式-桥接模式
设计模式·桥接模式
MinBadGuy8 小时前
【GeekBand】C++设计模式笔记5_Observer_观察者模式
c++·设计模式
刷帅耍帅8 小时前
设计模式-生成器模式/建造者模式Builder
设计模式·建造者模式
HealthScience1 天前
怎么将bash(sh)的所有输出保存到log/txt中?
开发语言·bash