您现在的位置是:首页 >技术杂谈 >设计模式第2讲——策略模式网站首页技术杂谈

设计模式第2讲——策略模式

无聊写写写 2024-07-15 12:01:02
简介设计模式第2讲——策略模式

目录

一、什么是策略模式

二、特点 

三、应用场景

四、策略模式实现

4.0、代码结构

 4.1、VideoContext

4.2、VideoStrategy

4.3、DyVideoStrategy 

4.4、KsVideoStrategy

4.5、WxVideoStrategy

4.6、TestStrategy

4.7、result


一、什么是策略模式

 一种行为型设计模式,它允许在运行时选择算法的行为。

1.概念       

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

2.组成

        环境(context):查询要做什么,得到具体要执行的策略。

        抽象策略(xxStategy):一个接口或抽象类。

        具体策略(xxStategy):具体算法或行为。

二、特点 

优点:

  • 算法可以自由切换。
  • 避免使用多重条件判断。
  • 扩展性良好

缺点:

  • 策略类会增多。
  • 所有策略类都需要对外暴露。
  • 判断逻辑在客户端,需求改变时,要更改客户端的程序。

三、应用场景

生活场景:

  • 手机开锁方式:密码、指纹、面部识别
  • 出游的交通方式:自驾、汽车、火车、飞机、高铁,每一种方式都是一个策略。
  • 开通csdn会员的方式:月卡、年卡、超级年卡、两年卡、连续包月。

代码场景: 以电商为例

  • 优惠券:满减、折扣、N元购。
  • 支付方式:零钱、微信、支付宝、银行卡。
  • 商品的类型:普通、秒杀、周期购、预售、限时特卖商品。

四、策略模式实现

我们将创建一个刷视频的VideoContext上下文类,一个VideoStrategy接口,和三个具体的策略实现类DyVideoStrategy、KsVideoStrategy、WxVideoStrategy并实现接口VideoStrategy

4.0、代码结构

 4.1、VideoContext

/**
 * 视频策略环境类(策略Bean的工厂)
 * 在初始化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;
    }
}

4.2、VideoStrategy

/**
 * 策略接口类
 */
public interface VideoStrategy {

    String brushVideo();

    String getVideoType();
}

4.3、DyVideoStrategy 

@Component
public class DyVideoStrategy implements VideoStrategy{
    @Override
    public String brushVideo() {
        return "我在刷抖音";
    }

    @Override
    public String getVideoType() {
        return "dy";
    }
}

4.4、KsVideoStrategy

@Component
public class KsVideoStrategy implements VideoStrategy{
    @Override
    public String brushVideo() {
        return "我在刷快手";
    }

    @Override
    public String getVideoType() {
        return "ks";
    }
}

4.5、WxVideoStrategy

@Component
public class WxVideoStrategy implements VideoStrategy{
    @Override
    public String brushVideo() {
        return "我在刷微信视频号";
    }

    @Override
    public String getVideoType() {
        return "wx";
    }
}

4.6、TestStrategy

import com.lky.designPattern.strategy.VideoContext;
import com.lky.designPattern.strategy.VideoStrategy;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
public class TestSource {

    @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);

    }
}

4.7、result

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。