设计模式行为型——策略模式

news2024/11/24 18:57:01

        在现实生活中常常遇到达成某种目的,有多种实现策略可供选择的情况。例如,出行上班可以乘坐公交车、乘坐地铁、骑自行车或自己开私家车等,填饱肚子可以吃火锅、吃烤肉、吃烤串、吃东北家常菜等方法。

        在软件开发中也常常遇到类似的情况,当实现某一个功能存在多种算法或者策略,可以根据环境或者条件的不同选择不同的算法或者策略来完成该功能,如数据排序策略有冒泡排序、选择排序、插入排序、堆排序、二叉树排序等。

        上述情况在软件开发中就对应策略模式,接下来,请进入策略模式的世界。

策略模式的定义

        策略模式(Strategy Pattern)属于行为型设计模式,其定义了一系列算法,并将每个算法封装起来,使他们可以相互替换,且算法的变化不会影响使用算法的客户。策略模式通过对算法进行封装,把使用算法的责任和算法的实现分割开来,并委派给不同的对象对这些算法进行管理。

        通过使用策略模式,可以在运行时根据需要选择不同的算法,而不需要修改客户端代码。在策略模式中,创建表示各种策略的对象和一个行为随着策略对象改变而改变的 context 对象。策略对象改变 context 对象的执行算法。

策略模式的实现

策略模式角色

  1. 环境角色(Context):维护一个对策略对象的引用,提供给客户端使用,负责将客户端请求委派给具体的策略对象执行。不需要知道具体策略类的实现细节,只需知道策略类实现了共同接口。环境类可以通过依赖注入、简单工厂等方式来获取具体策略对象。
  2. 抽象策略角色(Abstract Strategy):定义了策略对象的公共接口或抽象类,规定了具体策略类必须实现的方法。
  3. 具体策略角色(Concrete Strategy):实现了抽象策略定义的接口或抽象类,包含了具体的相关的算法和行为实现。

策略模式类图

策略模式举例

        在网购中,当需要进行在支付的时候,可以根据实际情况来选择不同的支付方式(微信支付、支付宝、银行卡支付等等),这些支付方式即是不同的策略。不同的支付方式就是不同的支付策略。

策略模式代码实现

抽象策略角色

package com.common.demo.pattern.strategy;

/**
 * @author Evan Walker 昂焱数据: https://www.ayshuju.com
 * @version 1.0
 * @desc 抽象策略角色 第三方支付
 * @date 2023/08/08 21:31:29
 */
public interface PaymentStrategy {

    /**
     * 获取支付方式
     *
     * @return 响应,支付方式
     */
    String getPayType();
}

具体策略角色

package com.common.demo.pattern.strategy;

/**
 * @author Evan Walker 昂焱数据: https://www.ayshuju.com
 * @version 1.0
 * @desc 具体策略角色 支付宝支付
 * @date 2023/08/08 21:30:54
 */
public class AlipayPaymentStrategy implements PaymentStrategy {

    @Override
    public String getPayType() {
        System.out.println("支付宝支付");
        return "支付宝支付";
    }
}
package com.common.demo.pattern.strategy;

/**
 * @author Evan Walker 昂焱数据: https://www.ayshuju.com
 * @version 1.0
 * @desc 具体策略角色 银行卡支付
 * @date 2023/08/08 21:30:54
 */
public class BankCardPaymentStrategy implements PaymentStrategy {

    @Override
    public String getPayType() {
        System.out.println("银行卡支付");
        return "银行卡支付";
    }
}
package com.common.demo.pattern.strategy;

/**
 * @author Evan Walker 昂焱数据: https://www.ayshuju.com
 * @version 1.0
 * @desc 具体策略角色 微信支付
 * @date 2023/08/08 21:30:54
 */
public class WxPaymentStrategy implements PaymentStrategy {

    @Override
    public String getPayType() {
        System.out.println("微信支付");
        return "微信支付";
    }
}

环境角色

package com.common.demo.pattern.strategy;

/**
 * @author Evan Walker 昂焱数据: https://www.ayshuju.com
 * @version 1.0
 * @desc 环境角色 环境
 * @date 2023/08/08 21:38:29
 */
public class Context {
    private PaymentStrategy paymentStrategy;

    public Context(PaymentStrategy paymentStrategy){
        this.paymentStrategy = paymentStrategy;
    }

    public String getPayType(){
        return paymentStrategy.getPayType();
    }
}

测试代码

package com.common.demo.pattern.strategy;

/**
 * @author Evan Walker 昂焱数据: https://www.ayshuju.com
 * @version 1.0
 * @desc 测试类
 * @date 2023/08/08 21:40:38
 */
public class Test {
    public static void main(String[] args) {
        Context alipay = new Context(new AlipayPaymentStrategy());
        System.out.println(alipay.getPayType());

        Context Wx = new Context(new WxPaymentStrategy());
        System.out.println(Wx.getPayType());

        Context bankcard = new Context(new BankCardPaymentStrategy());
        System.out.println(bankcard.getPayType());
    }
}

测试角色

策略模式的特点

优点

  1. 提高代码灵活性:策略模式可以将算法的选择和使用与客户端代码分离,使得算法可以独立演化和替换,提高了代码的灵活性。
  2. 易于扩展和维护:由于每个策略都是一个独立的类,所以新的策略可以相对容易地添加到系统中,同时也可以方便地修改或维护现有的策略类。
  3. 符合开闭原则:新增策略时无需修改原有代码,只需添加新的策略类即可。
  4. 职责分离:策略模式把算法的使用放到环境类中,而算法的实现移到具体策略类中,实现了二者的分离。

缺点

  1. 增加了类的数量:使用策略模式会增加多个策略类,导致类的数量增加。
  2. 客户端需要了解不同的策略:客户端需要了解所有可用的策略以及它们之间的区别,可能会增加客户端的复杂性。

使用场景

  1. 当有多个算法可以互相替换,并且客户端不应该知道具体的算法实现时,可以考虑使用策略模式。
  2. 当需要根据不同的情况选择不同的算法时,可以使用策略模式。
  3. 对客户隐藏具体策略(算法)的实现细节,彼此完全独立。

注意事项

  1. 策略间的平等性:在策略模式中,各个策略应该是平等的,没有优劣之分,它们只是针对同一问题的不同解决方案。
  2. 接口的定义和使用:在策略模式中,通常通过接口或抽象类定义策略,以便于扩展和替换。

实际应用

  1. 支付方式选择:一个电商系统可以根据用户的选择,采用不同的支付策略(如支付宝、微信支付、银行卡支付)。
  2. 排序算法:排序算法可以采用不同的策略实现(如冒泡排序、快速排序、归并排序)。
  3. 策略游戏中的战略选择:在策略游戏中,可以根据不同的战略选择不同的作战策略。

更多消息资讯,请访问昂焱数据(https://www.ayshuju.com)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/849939.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

人物启示-张一鸣与陆奇

在科技行业中,张一鸣与陆奇可谓是两位颇具影响力的人物。张一鸣和陆奇分别是字节跳动(TikTok 的母公司)的创始人和百度前总裁。张一鸣作为字节跳动的创始人,成功打造了今日头条、抖音等知名产品,而陆奇则曾任微软副总裁…

计算机组成与设计01:计算机的抽象与技术

目录 1 概述 1.1 计算机体系结构体中的8个伟大思想 1.2 计算机层次结构 1.2.1 概述 1.2.2 指令集体系结构 1.3 实例:从程序到电子信号 1.3.1 从高级语言到汇编语言 1.3.2 从汇编语言到机器语言 1.3.3 生成可执行文件并执行 1.3.4 计算机基本执行结构 1.3…

【vue3】基础知识点-computed和watch

学习vue3,都会从基础知识点学起。了解setup函数,ref,recative,watch、computed、pinia等如何使用 今天说vue3组合式api,computed和watch 在vue3中,computed和watch仍然是非常有用的特性,帮助处…

【C语言】实现linux下基于C语言的一个简单的UDP客/服端通信

一、实例代码 对于基础好的朋友可以直接拿代码看 客户端代码&#xff1a; #include <stdio.h> #include <sys/socket.h>//socket() #include <netinet/in.h>//struct sockaddr_in #include <string.h>//memset() #include <arpa/inet.h>//ine…

数字化转型中的抉择:定制化软件还是引入PDM系统?

企业在数字化转型过程中可以考虑是使用定制化软件、基于成熟模块改造&#xff0c;或引入PDM&#xff08;产品数据管理&#xff09;系统&#xff0c;这时需要仔细权衡各种因素&#xff0c;以确保选择最适合其需求的路径。这些选择各自有其优势和适用场景&#xff0c;下面将分别对…

Linux项目部署

目录 一JAVAWeb环境的部署【安装JDK&#xff0c;MySQL数据库&#xff0c;Tomcat】 二.手工部署SpringBoot项目&#xff08;写的最好的&#xff09; 1.在IDEA中开发SpringBoot项目并打成jar包--点击右侧的Maven执行package命令 2.将jar包上传到Linux服务器 3.执行以下命令&a…

探究Spring事务:了解失效场景及应对策略

在现代软件开发中&#xff0c;数据的一致性和完整性是至关重要的。为了保证这些特性&#xff0c;Spring框架提供了强大的事务管理机制&#xff0c;让开发者能够更加自信地处理数据库操作。然而&#xff0c;事务并非银弹&#xff0c;存在一些失效的情景&#xff0c;本文将带您深…

C++ Visual Studio工程目录相对路径设置

文章目录 相对路径相对路径是相对vs工程的哪个目录而言书写格式 参考 相对路径 要设对相对路径&#xff0c;需要搞清楚下面两个问题&#xff1a; 相对路径是相对vs工程的哪个目录而言相对路径的书写格式 相对路径是相对vs工程的哪个目录而言 注意&#xff1a; 并非以解决方案…

LeetCode150道面试经典题-买卖股票的最佳时机(简单)

1、题目 给定一个数组 prices &#xff0c;它的第 i 个元素 prices[i] 表示一支给定股票第 i 天的价格。 你只能选择 某一天 买入这只股票&#xff0c;并选择在 未来的某一个不同的日子 卖出该股票。设计一个算法来计算你所能获取的最大利润。 返回你可以从这笔交易中获取的…

麻了!包含中科院TOP,共16本期刊被标记为“On Hold”状态!

近日&#xff0c;小编从科睿唯安旗下的“Master Journal List”官网查到&#xff0c;除了知名老牌期刊Chemosphere竟然被标记为“On Hold”状态&#xff0c;目前共有7本SCI期刊&#xff0c;1本SSCI期刊&#xff0c;8本ESCI期刊被标记为“On Hold”&#xff0c;究竟是怎么回事呢…

一篇Android 真实面经(干货满满)

如梦朦胧 从年初开始就一直有换工作的躁动&#xff0c;因某些原因而拖到了现在,然后投了某度的Android岗位,本以为像我这种非211、985没工作经验的渣渣只能被直接pass,结果却意外的收到了电话,真是受宠若惊.经过电面,技术三面,然后就是等通知到最后拿到了OFFER,如梦一般,真是挺…

python小程序代码50 到100行,python小程序代码100行

这篇文章主要介绍了python小程序代码50 到100行&#xff0c;具有一定借鉴价值&#xff0c;需要的朋友可以参考下。希望大家阅读完这篇文章后大有收获&#xff0c;下面让小编带着大家一起了解一下。 目录 1.生成漂亮的樱花树2.绝美的静态樱花树3.魔法少女小圆动漫形象4.利用pyth…

【注册表】windows系统注册表常用修改方案

文章目录 ◆ 修改IE浏览器打印页面参数设置◆气泡屏幕保护◆彩带屏幕保护程序◆过滤IP(适用于WIN2000)◆禁止显示IE的地址栏◆禁止更改&#xff29;&#xff25;默认的检查(winnt适用)◆允许DHCP(winnt适用)◆局域网自动断开的时间(winnt适用)◆禁止使用“重置WEB设置”◆禁止更…

SHGetFileInfo函数获取48x48图标并在ListControl平铺视图中显示

VS2010工程下载链接&#xff1a;https://pan.baidu.com/s/1ACXQSpoNdFVFLdvWntT7mA?pwdwfy5 C语言写法&#xff1a; #define COBJMACROS #include <stdio.h> #include <Windows.h> #include <CommCtrl.h> #include <commoncontrols.h>HICON load_ic…

Cocos基本介绍

一、下载Dashboard Cocos Creator 3.8 手册 - 安装和启动 二、编辑器结构 1.资源管理器&#xff1a;显示了项目资源文件夹(assets)中的所有资源 2.场景编译器&#xff1a;用于展示和编辑场景中可是内容的工作区域 3.层级管理器&#xff1a;用树状列表的形式展示场景中的所有…

Linux文件读取

#include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h>int main(int argc, char * * argv){printf("输入了参数个数&#xff1a;%d \n",argc);if (argc !3 ){printf("参数不…

系统架构设计专业技能 · 软件工程(一)【系统架构设计师】

系列文章目录 系统架构设计高级技能 软件架构概念、架构风格、ABSD、架构复用、DSSA&#xff08;一&#xff09;【系统架构设计师】 系统架构设计高级技能 系统质量属性与架构评估&#xff08;二&#xff09;【系统架构设计师】 系统架构设计高级技能 软件可靠性分析与设计…

python接口自动化之正则用例参数化

前言 ​ 我们在做接口自动化的时候&#xff0c;处理接口依赖的相关数据时&#xff0c;通常会使用正则表达式来进行提取相关的数据。 ​ 正则表达式&#xff0c;又称正规表示式、正规表示法、正规表达式、规则表达式、常规表示法(Regular Expression&#xff0c;在代码中常简写…

目标检测YOLOv3基于DarkNet53模型测试-笔记

目标检测YOLOv3基于DarkNet53模型测试-笔记 预测和试测结果&#xff1a; 预测代码如下所示&#xff1a; testInsects.py #YOLOv3网模型测试-单图片文件测试并显示测试结果 import time import os import paddle import numpy as np import cv2 import random from PIL impor…

ROS实现自定义信息以及使用

常见的消息包 消息包定义一般如下&#x1f447; &#xff08;1&#xff09;创建包和依赖项 &#xff08;2&#xff09;在新建的qq_msgs的包新建msgs的文件夹&#xff0c;在该文件夹里面新建Carry.msg类型的文件。 其实&#xff0c;Carry.msg就是你自己定义的消息类型&am…