设计模式--策略模式【行为型模式】

devtools/2025/1/12 19:44:52/

设计模式的分类

我们都知道有 23 种设计模式,这 23 种设计模式可分为如下三类:

  • 创建型模式(5 种):单例模式、工厂方法模式、抽象工厂模式、建造者模式、原型模式。
  • 结构型模式(7 种):适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
  • 行为型模式(11 种):策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

在这里插入图片描述

设计模式系列文章传送门

设计模式的 7 大原则

设计模式–单例模式【创建型模式】

设计模式–工厂方法模式【创建型模式】

设计模式–抽象工厂模式【创建型模式】

设计模式–建造者模式【创建型模式】

设计模式–原型模式【创建型模式】

设计模式–适配器模式【结构型模式】

设计模式–装饰器模式【结构型模式】

设计模式–代理模式【结构型模式】

设计模式–外观模式(门面模式)【结构型模式】

设计模式–桥接模式【结构型模式】

设计模式–组合模式【结构型模式】

设计模式–享元模式【结构型模式】

什么是策略模式

策略模式是一个行为行设计模式,定义了一系列算法,并将每一个算法封装起来做为一个策略类,使的它们之间可以相互替换,策略模式可以让算法独立于客户端。

策略模式的组成部分

  • 上下文类:也叫环境类,它持有一个策略类的引用,通过策略类的方法来执行具体的算法,上下文类会提供一个统一的接口,可以让客户端访问不同的策略。
  • 抽象策略类:定义了一个统一的接口,让不同的策略类实现实现这个接口,从而实现具体的算法。
  • 具体策略类:实现了抽象策略类,并重写了抽象策略类中定义的统一接口,也就是实现了具体的算法,不同的具体策略类有不同的算法实现,它们之间可以相互替换,使得上下文类在运行时可以动态地改变策略。

策略模式案例演示

我们以春节回家购买火车票为案例,我们购买火车票可以选择 12306 官网购票、携程网购票、去哪儿网购票,假设张三、李四、王五分别要从三个客户端来完成买票,我们使用策略模式使用不同客户端买票。

BuyTicketsStrategy(抽象策略类)

BuyTicketsStrategy 买票抽象策略类,定义了买票方法,代码如下:

public interface BuyTicketsStrategy {//出发地  目的地void buyTickets(String user, String startPoint, String destination);}

BuyTicketsContext(上下文类)

BuyTicketsContext 上下文类,买票上下文类持有了一个买票抽象策略类对象,并调用了买票方法,代码如下:

public class BuyTicketsContext {//用户private String user;//出发地private String startPoint;//目的地private String destination;//买票策略类private BuyTicketsStrategy buyTicketsStrategy;public BuyTicketsContext(String user, String startPoint, String destination, BuyTicketsStrategy buyTicketsStrategy) {this.user = user;this.startPoint = startPoint;this.destination = destination;this.buyTicketsStrategy = buyTicketsStrategy;}//调用具体的策略类来买票public void buyTickets() {System.out.println(user + "买票出发了买票策略上下文");buyTicketsStrategy.buyTickets(user, startPoint, destination);}}

OfficialWebsiteBuyTicket(具体策略类)

OfficialWebsiteBuyTicket 12306 官网买票策略类,实现了买票抽象策略类,并重新了买票方法,代码如下:

public class OfficialWebsiteBuyTicket implements BuyTicketsStrategy{@Overridepublic void buyTickets(String user, String startPoint, String destination) {System.out.println("用户:" + user + "使用去12306官网买票,出发地:" + startPoint + ",目的地:" + destination);}
}

XieChengBuyTicket(具体策略类)

XieChengBuyTicket 携程买票策略类,实现了买票抽象策略类,并重新了买票方法,代码如下:

public class XieChengBuyTicket implements BuyTicketsStrategy {@Overridepublic void buyTickets(String user, String startPoint, String destination) {System.out.println("用户:" + user + "使用携程网买票,出发地:" + startPoint + ",目的地:" + destination);}
}

QuNaErBuyTicket(具体策略类)

QuNaErBuyTicket 去哪儿买票策略类,实现了买票抽象策略类,并重新了买票方法,代码如下:

public class QuNaErBuyTicket implements BuyTicketsStrategy {@Overridepublic void buyTickets(String user, String startPoint, String destination) {System.out.println("用户:" + user + "使用去哪儿网买票,出发地:" + startPoint + ",目的地:" + destination);}
}

BuyTicketClient(具体策略类)

客户端触发买票操作,代码如下:

public class BuyTicketClient {public static void main(String[] args) {//官网买票new BuyTicketsContext("张三", "北京", "上海", new OfficialWebsiteBuyTicket()).buyTickets();//携程买票new BuyTicketsContext("张三", "北京", "上海", new XieChengBuyTicket()).buyTickets();//去哪儿买票new BuyTicketsContext("张三", "北京", "上海", new QuNaErBuyTicket()).buyTickets();}}

买票结果如下:

张三买票出发了买票策略上下文
用户:张三使用去12306官网买票,出发地:北京,目的地:上海
张三买票出发了买票策略上下文
用户:张三使用携程网买票,出发地:北京,目的地:上海
张三买票出发了买票策略上下文
用户:张三使用去哪儿网买票,出发地:北京,目的地:上海

结果符合预期。

假设我们没有使用策略模式,如果要实现张三、李四、王五分别要从三个客户端来完成买票,则需要如下实现:

public class NoStrategyClient {public static void main(String[] args) {String user = "张三";if ("张三".equals(user)) {//官网买票OfficialWebsiteBuyTicket officialWebsiteBuyTicket = new OfficialWebsiteBuyTicket();officialWebsiteBuyTicket.buyTickets("张三", "北京", "上海");} else if ("李四".equals(user)) {//携程买票OfficialWebsiteBuyTicket officialWebsiteBuyTicket = new OfficialWebsiteBuyTicket();officialWebsiteBuyTicket.buyTickets("李四", "北京", "上海");} else if ("王五".equals(user)) {//去哪儿买票OfficialWebsiteBuyTicket officialWebsiteBuyTicket = new OfficialWebsiteBuyTicket();officialWebsiteBuyTicket.buyTickets("王五", "北京", "上海");}}}

可以看到如果不使用策略模式,则需要使用 if else 来完成,可见策略模式可以帮我们消除 if else,让代码看起来更优雅。

策略模式的优缺点

优点:

  • 策略模式实现了算法的定义和使用的分离,将不同的算法封装成相互独立的策略类,可以让算法可以独立变化,这提高了代码的灵活性和可维护性。
  • 扩展性良好,新加一个策略只需要新增一个策略类即可,无需修改其他代码。
  • 避免了条件语句的使用,代码更优雅。

优点:

  • 策略模式增加了代码量,增加了抽象策略类,上下文类,让系统变得更复杂。
  • 客户端需要知道具体的策略类,才知道如何选择,也就是说将算法的选择放在了客户端进行,增加了客户端代码的复杂性。

策略模式的使用场景

  • 当业务需要动态的在几种算法中选择一种时,可将种算法封装到策略类中,使用策略模式来实现。
  • 消除条件语句 if else。

总结:本篇简单分享了策略模式的概念及使用场景,并且使用多渠道买票场景来演示策略模式的使用,希望可以能够帮助不太熟悉策略模式的朋友加深对策略模式的理解。

如有不正确的地方欢迎各位指出纠正。


http://www.ppmy.cn/devtools/149552.html

相关文章

PHP多功能投票小程序源码

多功能投票小程序:全方位打造专属投票盛宴的得力助手 🎉 🔧 基于先进的ThinkPHP框架与Uniapp技术深度融合,我们匠心独运,精心雕琢出一款功能全面、操作便捷的投票小程序,旨在为您带来前所未有的投票体验。…

python学opencv|读取图像(二十九)使用cv2.getRotationMatrix2D()函数旋转缩放图像

【1】引言 前序已经学习了如何平移图像,相关文章链接为: python学opencv|读取图像(二十七)使用cv2.warpAffine()函数平移图像-CSDN博客 在此基础上,我们尝试旋转图像的同时缩放图像。 【2】…

如何进行单体前后端项目的微服务改造

如何进行单体前后端项目的微服务改造 引言 随着互联网技术的快速发展,传统的单体架构(Monolithic Architecture)逐渐显现出其局限性。对于大型应用来说,单体架构可能会导致开发效率低下、部署困难以及扩展性差等问题。因此&…

Postman接口测试03|执行接口测试、全局变量和环境变量、接口关联、动态参数、断言

目录 七、Postman 1、安装 2、postman的界面介绍 八、Postman执行接口测试 1、请求页签 3、响应页签 九、Postman的环境变量和全局变量 1、创建环境变量和全局变量可以解决的问题 2、postman中的操作-全局变量 1️⃣手动设置 2️⃣代码设置 3️⃣界面获取 4️⃣代…

RabbitMQ基础(简单易懂)

什么是RabbitMQ? 它基于AMQP协议(Advanced Message Queuing Protocol),一种为应用构建消息队列的标准协议。过程中,它提供了一些重要模块:为消息发送的Producer(生产者)&#xff0c…

C++ 的 pair 和 tuple

1 std::pair 1.1 C 98 的 std::pair 1.1.1 std::pair 的构造 ​ C 的二元组 std::pair<> 在 C 98 标准中就存在了&#xff0c;其定义如下&#xff1a; template<class T1, class T2> struct pair;std::pair<> 是个类模板&#xff0c;它有两个成员&#x…

Java聊天小程序

拟设计一个基于 Java 技术的局域网在线聊天系统,实现客户端与服务器之间的实时通信。系统分为客户端和服务器端两类,客户端用于发送和接收消息,服务器端负责接收客户端请求并处理消息。客户端通过图形界面提供用户友好的操作界面,服务器端监听多个客户端的连接并管理消息通…

大模型WebUI:Gradio全解11——Chatbots:融合大模型的多模态聊天机器人(2)

大模型WebUI&#xff1a;Gradio全解11——Chatbots&#xff1a;融合大模型的聊天机器人&#xff08;2&#xff09; 前言本篇摘要11. Chatbot&#xff1a;融合大模型的多模态聊天机器人11.2 使用流行的LLM库和API11.2.1 Llama Index11.2.2 LangChain11.2.3 OpenAI1. 基本用法2. …