[设计模式] 行为型:策略模式(Strategy Pattern)

2024-06-10 07:48

本文主要是介绍[设计模式] 行为型:策略模式(Strategy Pattern),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章标题

    • 什么是策略模式
    • 设计与实现
    • 总结

什么是策略模式

策略,就是解决问题的具体方法。针对同一个问题的不同条件,可以有多种不同的解决方法。

比如,外出旅行,可选的出行方式有:汽车(省内旅行)、火车(国内旅行)、飞机(国际旅行)。每一种出行方式都是一种具体的策略,各自都有对应的选择条件。

如果把这个场景用代码表示出来,最容易想到的应该就是用if...else...来实现。但是,这在编程老鸟眼里是有问题的,后期扩展性不佳。

简单解释下为什么扩展性不佳,随着场景的丰富,策略选择条件可能会更复杂,也可能会增加新的策略。比如说,省内旅行不一定都选择汽车,如果坐火车更快,那就是更好的选择;再比如说,要去太空旅行,汽车、火车、飞机都无法满足,就得考虑新增“飞船”的选项了。

每当变化发生的时候,if...else...就得跟着变化,试想一下,在条件复杂、交通工具很多的场景下,if...else...会是怎样的臃肿!

这样的代码看着不爽,后期自己看逻辑可能也会懵逼,交接出去后别人大概率还会骂你。

为了避免臃肿的if...else...,可以选用策略模式,考虑用“面向对象思想”解决问题。两者考虑问题的思路稍有不同:

  1. if...else...思路:我要旅行,现在需要选择一种交通工具,省内旅行就坐汽车,国内旅行就坐火车,国际旅行就坐飞机,选择好以后,出发去旅行
  2. 策略模式思路:我要旅行,去找个导游,帮我选择交通工具,选择好以后,出发去旅行

两者不同之处:策略选择谁去做?

if...else...下,旅行者不仅提出条件,还要做出交通选择。

在策略模式下,旅行者只需提出条件,交通策略交由导游选择。

设计与实现

无论是用if...else...,还是用策略模式,代码中都有一些固定不变的对象定义:一个要旅行者,三种交通工具,汽车、火车、飞机。

public interface Transport { // 出行工具的抽象void go();// 出行
}public class Car implements Transport { // 汽车@Overridepublic void go() { System.out.println("汽车出行"); }
}public class Train implements Transport { // 火车@Overridepublic void go() { System.out.println("火车出行"); }
}public class Airplane implements Transport { // 飞机@Overridepublic void go() { System.out.println("飞机出行"); }
}public class Passenger { // 乘客private Integer condition; // 出行条件:1-省内旅行,2-国内旅行,3-国际旅行private Transport transport; // 出行工具public Passenger(Integer condition) { this.condition = condition; }public Integer getCondition() { return condition; }public void setTransport(Transport transport) { this.transport = transport; }public void travel() { transport.go(); } // 旅行
}

基本对象类都定义好了,具体场景逻辑用if...else...实现,如下:

// 具体场景下的策略选择逻辑
public static void main(String[] args) {Passenger passenger = new Passenger(1);if (passenger.getCondition() == 1) { // 省内旅行,选择汽车passenger.setTransport(new Car());} else if (passenger.getCondition() == 2) { // 国内旅行,选择火车passenger.setTransport(new Train());} else if (passenger.getCondition() == 3) { // 国际旅行,选择飞机passenger.setTransport(new Airplane());} else {System.out.println("非法场景!");}passenger.travel();// 旅行者出发去旅行
}

由于场景简单,这段代码看着也挺简洁。但是,这段场景代码还是耦合了两个逻辑:

  1. 自身旅行逻辑:有旅行想法,选择出行工具,出发旅行
  2. 交通选择逻辑:省内旅行选择汽车,国内旅行选择火车,国际旅行选择飞机

如果是现实生活中的自由旅行,这就是很正常的事情,所有过程细节都需要旅行者自己考虑选择清楚。

作为一个就想旅游放松几天的旅行者,事无巨细都要考虑,也是一件蛮累的事情。

那就找个导游,减轻一些旅行者的工作,让旅行者专注于旅行本身,交通工具的选择就交给专业的导游吧。

这就是策略模式要做的事情,专业的策略选择交给专业的对象去做。

定义一个策略决策者,也就是导游:

public class Guide {Map<Integer, Transport> map = new HashMap<>(); // 所有的策略条件public Guide() {map.put(1, new Car()); // 省内旅行,选择汽车map.put(2, new Train()); // 国内旅行,选择火车map.put(3, new Airplane()); // 国际旅行,选择飞机}public Transport chooseTransport(Integer condition) { return map.get(condition); }
}

有了这个导游做决策,旅行者的旅行就会很轻松,只需享受旅行本身就好。

public static void main(String[] args) {Guide guide = new Guide();Passenger passenger = new Passenger(1); // 旅行者确定出行条件Transport transport = guide.chooseTransport(passenger.getCondition()); // 导游选择交通策略passenger.setTransport(transport);passenger.travel();// 出发去旅行
}

这样的场景代码是不是看着就很友好?旅行者没有太多的选择条件要去思考,只需专心享受旅行就好。

总结

策略模式主要用在选择复杂的场景中,将复杂业务中“策略选择”这件事情独立出来,形成通用组件,可以提高程序后期的维护性与扩展性。

凡事不要绝对化,在简单场景中,还是尽量优先选用if...else...,因为代码好写并且直观,代码量相对也比较少。

策略模式可以认为是if...else...的升级版本,当if...else...逐渐臃肿到人类思维都觉的复杂时,就该考虑用策略模式重构它了。

这篇关于[设计模式] 行为型:策略模式(Strategy Pattern)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1047566

相关文章

在JS中的设计模式的单例模式、策略模式、代理模式、原型模式浅讲

1. 单例模式(Singleton Pattern) 确保一个类只有一个实例,并提供一个全局访问点。 示例代码: class Singleton {constructor() {if (Singleton.instance) {return Singleton.instance;}Singleton.instance = this;this.data = [];}addData(value)

模版方法模式template method

学习笔记,原文链接 https://refactoringguru.cn/design-patterns/template-method 超类中定义了一个算法的框架, 允许子类在不修改结构的情况下重写算法的特定步骤。 上层接口有默认实现的方法和子类需要自己实现的方法

【iOS】MVC模式

MVC模式 MVC模式MVC模式demo MVC模式 MVC模式全称为model(模型)view(视图)controller(控制器),他分为三个不同的层分别负责不同的职责。 View:该层用于存放视图,该层中我们可以对页面及控件进行布局。Model:模型一般都拥有很好的可复用性,在该层中,我们可以统一管理一些数据。Controlller:该层充当一个CPU的功能,即该应用程序

迭代器模式iterator

学习笔记,原文链接 https://refactoringguru.cn/design-patterns/iterator 不暴露集合底层表现形式 (列表、 栈和树等) 的情况下遍历集合中所有的元素

《x86汇编语言:从实模式到保护模式》视频来了

《x86汇编语言:从实模式到保护模式》视频来了 很多朋友留言,说我的专栏《x86汇编语言:从实模式到保护模式》写得很详细,还有的朋友希望我能写得更细,最好是覆盖全书的所有章节。 毕竟我不是作者,只有作者的解读才是最权威的。 当初我学习这本书的时候,只能靠自己摸索,网上搜不到什么好资源。 如果你正在学这本书或者汇编语言,那你有福气了。 本书作者李忠老师,以此书为蓝本,录制了全套视频。 试

利用命令模式构建高效的手游后端架构

在现代手游开发中,后端架构的设计对于支持高并发、快速迭代和复杂游戏逻辑至关重要。命令模式作为一种行为设计模式,可以有效地解耦请求的发起者与接收者,提升系统的可维护性和扩展性。本文将深入探讨如何利用命令模式构建一个强大且灵活的手游后端架构。 1. 命令模式的概念与优势 命令模式通过将请求封装为对象,使得请求的发起者和接收者之间的耦合度降低。这种模式的主要优势包括: 解耦请求发起者与处理者

springboot实战学习(1)(开发模式与环境)

目录 一、实战学习的引言 (1)前后端的大致学习模块 (2)后端 (3)前端 二、开发模式 一、实战学习的引言 (1)前后端的大致学习模块 (2)后端 Validation:做参数校验Mybatis:做数据库的操作Redis:做缓存Junit:单元测试项目部署:springboot项目部署相关的知识 (3)前端 Vite:Vue项目的脚手架Router:路由Pina:状态管理Eleme

状态模式state

学习笔记,原文链接 https://refactoringguru.cn/design-patterns/state 在一个对象的内部状态变化时改变其行为, 使其看上去就像改变了自身所属的类一样。 在状态模式中,player.getState()获取的是player的当前状态,通常是一个实现了状态接口的对象。 onPlay()是状态模式中定义的一个方法,不同状态下(例如“正在播放”、“暂停

软件架构模式:5 分钟阅读

原文: https://orkhanscience.medium.com/software-architecture-patterns-5-mins-read-e9e3c8eb47d2 软件架构模式:5 分钟阅读 当有人潜入软件工程世界时,有一天他需要学习软件架构模式的基础知识。当我刚接触编码时,我不知道从哪里获得简要介绍现有架构模式的资源,这样它就不会太详细和混乱,而是非常抽象和易

使用Spring Boot集成Spring Data JPA和单例模式构建库存管理系统

引言 在企业级应用开发中,数据库操作是非常重要的一环。Spring Data JPA提供了一种简化的方式来进行数据库交互,它使得开发者无需编写复杂的JPA代码就可以完成常见的CRUD操作。此外,设计模式如单例模式可以帮助我们更好地管理和控制对象的创建过程,从而提高系统的性能和可维护性。本文将展示如何结合Spring Boot、Spring Data JPA以及单例模式来构建一个基本的库存管理系统