设计模式12之策略模式

28 篇文章 0 订阅
1 篇文章 0 订阅

背景

策略模式是一种比较简单的设计模式,生活中做成一件事有几种不同的策略选择供你达成。比如你上班可以选择坐公交上班,可以选择坐地铁上班,也可以选择自驾上班,甚至还可以步行上班。

如果需要用代码表示上面的内容,你可以使用多重条件语句实现。

if("1".equals(status)) {
   return "公交";
} else if("2".equals(status)) {
   return "地铁";
} else if("3".equals(status)) {
   return "自驾";
} else if("4".equals(status)) {
   return "步行";
} 

但是上面这样的代码实际就是硬编码,如果需要增加、移除、修改算法,需要在这里修改,违反了开闭原则。这个问题可以使用策略模式解决。

如果使用if语句,大概是这样的一个流程图:

if语句

使用策略模式的流程图:

策略模式

什么是策略模式

Define a family of algorithms,encapsulate each one,and make them interchangeable.(定义一组算法,将每个算法都封装起来,并且使它们之间可以互换。)

将算法调用方与算法实现方分割开来,实现两者之间的解耦。

策略模式的主要组成要素如下:

  • 抽象策略(Strategy)类:定义了一个公共接口,各种不同的算法以不同的方式实现这个接口,环境角色使用这个接口调用不同的算法,一般使用接口或抽象类实现。

  • 具体策略(Concrete Strategy)类:实现了抽象策略定义的接口,提供具体的算法实现。

  • 环境(Context)类:持有一个策略类的引用,最终给客户端调用。

代码实现

How2WorkStrategy

抽象策略类

interface How2WorkStrategy {
    String how2WorkFun();
}

SubwayStrategy

地铁策略类

public class SubwayStrategy implements How2WorkStrategy{
    @Override
    public String how2WorkFun() {
        return "地铁";
    }
}

CarStrategy

自驾小车策略类

public class CarStrategy implements How2WorkStrategy{
    @Override
    public String how2WorkFun() {
        return "自驾";
    }
}

BusStrategy

公交车策略类

public class BusStrategy implements How2WorkStrategy{
    @Override
    public String how2WorkFun() {
        return "公交";
    }
}

WalkStrategy

步行策略类

public class WalkStrategy implements How2WorkStrategy{
    @Override
    public String how2WorkFun() {
        return "步行";
    }
}

Context

装载类,可理解为策略工厂。

public class Context {
    public How2WorkStrategy getHow2WorkStrategy() {
        return how2WorkStrategy;
    }

    public void setHow2WorkStrategy(How2WorkStrategy how2WorkStrategy) {
        this.how2WorkStrategy = how2WorkStrategy;
    }

    private How2WorkStrategy how2WorkStrategy;

    public String how2Work() {
        return how2WorkStrategy.how2WorkFun();
    }

}

测试代码:

@org.junit.Test
public void test() {
    Context context = new Context();
    How2WorkStrategy how2WorkStrategy = new CarStrategy();
    context.setHow2WorkStrategy(how2WorkStrategy);
    String s = context.how2Work();
    Console.log(s);
    Console.log("---------------------");
    how2WorkStrategy = new BusStrategy();
    context.setHow2WorkStrategy(how2WorkStrategy);
    String s1 = context.how2Work();
    Console.log(s1);
}

我们选择自驾策略和公交车策略,测试结果如下:

自驾
---------------------
公交

上面代码还有缺限,上层模块必须知道有哪些策略,然后才能决定使用哪一个策略,这与迪米特法则是相违背的,我只是想使用了一个策略,我凭什么就要了解这个策略呢?那要你的封装类还有什么意义?这是原装策略模式的一个缺点,幸运的是,我们可以使用其他模式来修正这个缺陷,如工厂方法模式、代理模式或享元模式。

关于改进方法,有兴趣的还可以看看我的这篇文章:

👉公司系统if-else语句太多了,我用设计模式消除了if-else

关于策略模式的思考

策略模式比较简单,如果存在多重if语句。并且if语句还有可能变化,那么我们就可以将if语句中的算法封装到类中,使用策略模式代替if语句。

总之策略模式就是:算法可自由切换、避免多重if-else语句、更好的扩展性。

往期推荐

扫码二维码,获取更多精彩。或微信搜Lvshen_9,可后台回复获取资料

1.回复"java" 获取java电子书;

2.回复"python"获取python电子书;

3.回复"算法"获取算法电子书;

4.回复"大数据"获取大数据电子书;

5.回复"spring"获取SpringBoot的学习视频。

6.回复"面试"获取一线大厂面试资料

7.回复"进阶之路"获取Java进阶之路的思维导图

8.回复"手册"获取阿里巴巴Java开发手册(嵩山终极版)

9.回复"总结"获取Java后端面试经验总结PDF版

10.回复"Redis"获取Redis命令手册,和Redis专项面试习题(PDF)

11.回复"并发导图"获取Java并发编程思维导图(xmind终极版)

另:点击【我的福利】有更多惊喜哦。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值