【Java设计模式】行为型设计模式-策略模式(十三)

策略模式

  • 策略模式将各种不同类型所对应的不同执行逻辑抽象成算法族(策略组),并分别封装起来,让他们之间可以互相替换,这样就将算法的变化和使用算法的客户端分离开来。
  • 这样体现了几个设计原则:
    • 把变化的代码从不变的代码中分离出来。
    • 针对接口编程而不是具体类(定义了策略接口)。
    • 多用组合/聚合,少用继承(客户通过组合方式使用策略)。

进一步阐述:策略模式就是解决具体逻辑和客户端耦合在一起的问题,其核心是找到项目中变化的部分并进行抽离出来成为一个接口,项目中不变的部分就直接使用接口调用抽象方法即可。

策略模式包含三种角色:

  • Context(环境角色):用来操作策略的上下文环境,它持有一个Strategy的引用。
  • Strategy(抽象策略角色):所有策略的抽象,封装了需要去执行的项目中不变的部分逻辑。
  • ConcreteStrategy (具体策略角色):抽象策略的实现,每一种不同的逻辑执行方式就是一个具体的策略类。

案例:我们以一个旅行者为例,旅行的方式有很多种,可以坐高铁,也可以坐飞机,这取决于用户自己的选择。其中旅行者Traveler类就是环境角色,旅行策略TravelingStrategy接口就是抽象策略角色,飞机旅行策略AirTravelingStrategy实现类和高铁旅行策略HightTrainTravelingStrategy实现类就是具体的策略角色。

UML类图:

客户端Client类:

java 复制代码
/**
 * 客户端
 */
public class Client {
​
    public static void main(String[] args) {
​
        Traveler traveler = new Traveler(new HightTrainTravelingStrategy());
​
        traveler.goTraveling();
    }
}

旅行者Traveler类:

java 复制代码
/**
 * 旅行者类
 */
public class Traveler {
​
    //持有一个旅行策略接口的实现类
    private TravelingStrategy travelingStrategy;
​
    public Traveler(TravelingStrategy travelingStrategy) {
        this.travelingStrategy = travelingStrategy;
    }
​
    public void goTraveling() {
        //省去了繁琐的if-- else if -- else if
        travelingStrategy.goTraveling();
    }
}

旅行策略TravelingStrategy接口:

java 复制代码
/**
 * 旅行策略接口
 */
public interface TravelingStrategy {
​
    /**
     * 去旅游方法
     */
    void goTraveling();
}

高铁旅行策略HightTrainTravelingStrategy实现类:

java 复制代码
/**
 * 高铁旅行策略实现类
 */
public class HightTrainTravelingStrategy implements TravelingStrategy {
​
    @Override
    public void goTraveling() {
        System.out.println("乘坐高铁去旅行......");
    }
}

飞机旅行策略AirTravelingStrategy实现类:

java 复制代码
/**
 * 飞机旅行策略实现类
 */
public class AirTravelingStrategy implements TravelingStrategy {
​
    @Override
    public void goTraveling() {
        System.out.println("乘坐飞机去旅行......");
    }
}

总结:

  • 客户端增加行为不用修改原有代码,只要添加一种策略(或者行为)即可,避免了使用if--else if--else if去完成逻辑的编程的情况,是典型的if--else if--else if的"杀手",因为遵守了开闭原则(OCP原则),所以极大地提高了软件的可扩展性、可维护性。
  • 策略模式的核心思想是:多用组合或者聚合少用继承;用行为类进行组合,而不是行为类进行继承,这样耦合度降低了,这样就替换了用继承关系解决问题的办法,策略模式将算法封装在独立的 Strategy 类中使得你可以独立于其 Context 改变它,使它易于切换、易于理解、易于扩展遵守了合成复用原则。
  • 使用策略模式的客户端必须知道所有的策略类,并自行决定使用哪一个策略类。
  • 策略模式如果策略有很多那么就会出现很多的策略类增加了系统类的复杂度。
  • Context在使用这些策略类的时候,这些策略类由于实现了策略接口,所以有些数据可能用不到,但是依然初始化了,这样就造成了内存的浪费。

典型运用场景举例: 电商项目的优惠活动管理,优惠的策略有很多种,包括满减类型优惠策略、打折类优惠策略、赠送礼品策略、发放优惠券策略。

相关推荐
Rverdoser15 分钟前
RabbitMQ的基本概念和入门
开发语言·后端·ruby
dj244294570718 分钟前
JAVA中的Lamda表达式
java·开发语言
工业3D_大熊32 分钟前
3D可视化引擎HOOPS Luminate场景图详解:形状的创建、销毁与管理
java·c++·3d·docker·c#·制造·数据可视化
szc176735 分钟前
docker 相关命令
java·docker·jenkins
程序媛-徐师姐1 小时前
Java 基于SpringBoot+vue框架的老年医疗保健网站
java·vue.js·spring boot·老年医疗保健·老年 医疗保健
yngsqq1 小时前
c#使用高版本8.0步骤
java·前端·c#
尘浮生1 小时前
Java项目实战II基于微信小程序的校运会管理系统(开发文档+数据库+源码)
java·开发语言·数据库·微信小程序·小程序·maven·intellij-idea
小白不太白9501 小时前
设计模式之 模板方法模式
java·设计模式·模板方法模式
Tech Synapse1 小时前
Java根据前端返回的字段名进行查询数据的方法
java·开发语言·后端
.生产的驴1 小时前
SpringCloud OpenFeign用户转发在请求头中添加用户信息 微服务内部调用
spring boot·后端·spring·spring cloud·微服务·架构