【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在使用这些策略类的时候,这些策略类由于实现了策略接口,所以有些数据可能用不到,但是依然初始化了,这样就造成了内存的浪费。

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

相关推荐
Re.不晚4 分钟前
Java入门15——抽象类
java·开发语言·学习·算法·intellij-idea
雷神乐乐10 分钟前
Maven学习——创建Maven的Java和Web工程,并运行在Tomcat上
java·maven
码农派大星。13 分钟前
Spring Boot 配置文件
java·spring boot·后端
顾北川_野20 分钟前
Android 手机设备的OEM-unlock解锁 和 adb push文件
android·java
江深竹静,一苇以航23 分钟前
springboot3项目整合Mybatis-plus启动项目报错:Invalid bean definition with name ‘xxxMapper‘
java·spring boot
confiself38 分钟前
大模型系列——LLAMA-O1 复刻代码解读
java·开发语言
Wlq041543 分钟前
J2EE平台
java·java-ee
XiaoLeisj1 小时前
【JavaEE初阶 — 多线程】Thread类的方法&线程生命周期
java·开发语言·java-ee
杜杜的man1 小时前
【go从零单排】go中的结构体struct和method
开发语言·后端·golang
幼儿园老大*1 小时前
走进 Go 语言基础语法
开发语言·后端·学习·golang·go