【设计模式】第十四章:策略模式详解及应用案例

news2024/9/20 9:08:55

系列文章

【设计模式】七大设计原则
【设计模式】第一章:单例模式
【设计模式】第二章:工厂模式
【设计模式】第三章:建造者模式
【设计模式】第四章:原型模式
【设计模式】第五章:适配器模式
【设计模式】第六章:装饰器模式
【设计模式】第七章:代理模式
【设计模式】第八章:桥接模式
【设计模式】第九章:外观模式 / 门面模式
【设计模式】第十章:组合模式
【设计模式】第十一章:享元模式
【设计模式】第十二章:观察者模式
【设计模式】第十三章:模板方法模式
【设计模式】第十四章:策略模式
【设计模式】第十五章:责任链模式
【设计模式】第十六章:迭代器模式
【设计模式】第十七章:状态模式
【设计模式】第十八章:备忘录模式
【设计模式】第十九章:访问者模式
【设计模式】第二十章:解释器模式
【设计模式】第二十一章:命令模式
【设计模式】第二十二章:中介者模式


文章目录

  • 系列文章
  • 一、定义
  • 二、角色分类
  • 三、实现方式
    • UML图
    • 具体实现
  • 四、应用场景
  • 五、优缺点
    • 优点
    • 缺点


一、定义

摘自菜鸟教程: 在策略模式(Strategy Pattern)中,一个类的行为或其算法可以在运行时更改。这种类型的设计模式属于行为型模式。

在策略模式中,我们创建表示各种策略的对象和一个行为随着策略对象改变而改变的 context 对象。策略对象改变 context 对象的执行算法。


二、角色分类

上下文角色(Context)

上层访问策略的入口,它具有抽象策略角色的引用

抽象策略角色(Strategy)

它是接口或抽象类,其定义了一个算法簇,具体策略组必须要拥有的方法和属性

具体策略角色(Concrete Strategy)

实现抽象策略,定义具体的算法逻辑

客户角色(Client)

具体调用方法的角色


三、实现方式

UML图

Image.png

具体实现

假如我们在外买东西需要付钱,有多个付款方式供我们选择,我们可以用策略模式来实现。

抽象策略角色(Strategy)

public interface PayStrategy {

  /**
   * 付款
   */
  void pay();
}

具体策略角色(Concrete Strategy)

public class WechatPayStrategy implements PayStrategy {
  @Override
  public void pay() {
    System.out.println("使用微信支付");
  }
}

public class AliPayStrategy implements PayStrategy {
  @Override
  public void pay() {
    System.out.println("使用支付宝支付");
  }
}

public class CashPayStrategy implements PayStrategy {
  @Override
  public void pay() {
    System.out.println("使用现金支付");
  }
}

上下文角色(Context)

public class PayStrategyContext {

  private final PayStrategy strategy;

  public PayStrategyContext(PayStrategy strategy) {
    this.strategy = strategy;
  }

  public void payment() {
    strategy.pay();
  }
}

客户角色(Client)

public class Client {
  public static void main(String[] args) {
    PayStrategyContext context = new PayStrategyContext(new WechatPayStrategy());
    context.payment();

    context = new PayStrategyContext(new AliPayStrategy());
    context.payment();

    context = new PayStrategyContext(new CashStrategy());
    context.payment();
    
  }
}

运行结果

使用微信支付
使用支付宝支付
使用现金支付

四、应用场景

以下部分内容摘自菜鸟教程

意图: 定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。

主要解决: 在有多种算法相似的情况下,使用 if…else 所带来的复杂和难以维护。

何时使用: 一个系统有许多许多类,而区分它们的只是他们直接的行为。

如何解决: 将这些算法封装成一个一个的类,任意地替换。

关键代码: 实现同一个接口。

应用实例:

  1. 诸葛亮的锦囊妙计,每一个锦囊就是一个策略。
  2. 旅行的出游方式,选择骑自行车、坐汽车,每一种旅行方式都是一个策略。
  3. JAVA AWT 中的 LayoutManager。

使用场景:

  1. 如果在一个系统里面有许多类,它们之间的区别仅在于它们的行为,那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为。
  2. 一个系统需要动态地在几种算法中选择一种。
  3. 如果一个对象有很多的行为,如果不用恰当的模式,这些行为就只好使用多重的条件选择语句来实现。

注意事项: 如果一个系统的策略多于四个,就需要考虑使用混合模式,解决策略类膨胀的问题。


五、优缺点

优点

  1. 算法可以自由切换。
  2. 避免使用多重条件判断。
  3. 扩展性良好。

缺点

  1. 策略类会增多。
  2. 所有策略类都需要对外暴露。

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

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

相关文章

scanpy sc.pp.normalize_per_cell bug

今天遇到一个很奇怪的bug, 当今天跑covid_atlas数据集的时候,在123服务器总是报错,但是我记得在122服务器上是跑过没问题的 最终的测试结果如下 import scanpy as sc import numpy as np from QUEST import QUEST from QUEST.utils import get_free_…

【MySQL】简介 MySQL 事务

一、事务 ACID 原则 什么是事务呢?事务通常是一个或一组 SQL 组成的,组成一个事务的 SQL 一般都是一个业务操作,例如下单操作:【扣库存数量、增加订单详情记录、插入物流信息】,这一组 SQL 就可以组成一个事务。 而数据…

推特开始限制用户可以阅读的推文数量

推特正在限制用户可以阅读的推文数量,因为埃隆马斯克 (Elon Musk) 拥有的服务长期中断,阻碍了用户跟踪新帖子的能力。 在一条推文中,马斯克详细介绍了修改后的使用配额。 经过验证的帐户持有者每天最多可以浏览 6000 个帖子,而未…

docker的联合文件系统 UnionFS《深入docker底层原理》

介绍 docker最大的贡献就是定义了容器镜像的分层的存储格式,docker镜像技术的基础是联合文件系统(UnionFS),其文件系统是分层的。这样既可以充分利用共享层,又可以减少存储空间占用。 联合挂载系统的工作原理:读:如果…

结束 guard else 只能使用 return ?

Guard 语句 A guard statement is used to transfer program control out of a scope if one or more conditions aren’t met. 如果一个或者多个条件不成立,可用 guard 语句来退出当前作用域 (guard所在的作用域)。 Statement Form 语句格式 guard condition1, co…

软件设计模式与体系结构-设计模式-行为型软件设计模式-中介者模式

三、中介者模式(迪米特法则) 概念 模式动机: 为了减少对象两之间复杂的引用关系,使之成为一个松耦合的系统,需要适用中介者模式 定义: 用一个中介对象来封装一系列的对象交互,中介者使各对象…

从0开始,手写Redis

说在前面 从0开始,手写一个Redis的学习价值在于: 可以深入地理解Redis的内部机制和原理,Redis可谓是面试的绝对重点和难点从而更好地掌握Redis的使用和优化帮助你提高编程能力和解决问题的能力手写一个Redis可以作为一个优质的简历轮子项目…

LVS和keepalived群集

LVS和keepalived群集 一、keepalived概述:1.keepalived服务的重要功能:2.高可用故障切换转移原理:3.keepalived实现原理剖析:4.keepalived体系主要模块及作用:5.keepalived的工作原理: 二、部署LVS和keepal…

Android JetPack深入分析DataBinding源码

前言 数据绑定库是一种支持库,借助该库,您可以使用声明性格式(而非程序化地)将布局中的界面组件绑定到应用中的数据源。 DataBinding支持双向绑定,数据变化的时候界面跟着变化,界面变化也同步给数据&…

华为6605AC控制器大型组网wlan pool技术应用(自动漫游)

AC命令行配置: dis current-configuration set memory-usage threshold 0 ssl renegotiation-rate 1 vlan batch 100 vlan pool vlan_pool_test vlan 11 to 12 diffserv domain default radius-server template default free-rule-template name default_free_rule …

win10通过conda安装pytorch gpu

1. 安装anaconda 到官网下载最新版的anaconda,下载对应的windows版本,地址:anaconda官网 下载后直接安装,安装完成后配置环境变量,具体可以百度anaconda安装说明。安装完成后,打开cmd,输入conda…

Leetcode - 352周赛详解

一,最长奇偶子数组 看题可知可以使用暴力求解,从头开始遍历数组,另设一个变量来记录满足条件的子数组长度的最大值,将该变量不断与新得到的子数组长度比较,最终得到子数组长度的最大值。但是这样依次遍历的话&#xff…

git 分支管理

目录 一. 理解分支 1. master分支 二. 分支的(创建,切换、合并、删除) 1.查看分支 2.创建分支 3. 切换分支 4. 合并分支 5. 删除分支 三. 合并冲突 四. 合并模式 五. bug 分支 六. 强制删除分支 一. 理解分支 1. master分支 在我们的…

省电,AMD 提交 Linux 新技术 FreeSync Panel Replay

导读AMD 近日发布了一系列补丁,为其 AMDGPU Linux 内核显卡驱动程序的显示代码 “DC” 添加了一个新功能:FreeSync Panel Replay。这个功能针对搭载 DCN v3.1.4 显示块或更新版本的 AMD Ryzen 笔记本电脑,可以在屏幕内容不变时降低功耗。 目…

关于https的加密流程简介(图解)

目录 对称加密: 非对称加密 对称加密: 在网络发展的初阶,为了保护数据安全,防止黑客攻击,我们发明了对称加密 即一把秘钥,客户端和服务器通过这把钥匙对数据进行加密/解密 理想情况下,只要没…

第163天:应急响应-后门攻击检测指南Rookit内存马权限维持WINLinux

知识点 #知识点 -网页篡改与后门攻击防范应对指南 主要需了解:异常特征,处置流程,分析报告等 主要需了解:日志存储,Webshell检测,分析思路等 掌握: 中间件日志存储,日志格式内容介绍…

Qt之QMainWindow 自定义标题栏

简述 Qt自带标题栏功能还是很强大的,但是确实不能百分百满足需求,除了丑以外还不能随意更改标题栏字体,也不能更改样式;所以为了满足自己的虚荣心让标题栏变得更加好用看好看,特地花时间做了以下测试; 支持…

MySQL:数据的增删改查

数据的增删改查 前言一、插入数据1、实际问题2、方式1:VALUES的方式添加3、方式2:将查询结果插入到表中 二、删除数据三、更新数据四、查询数据五、MySQL8新特性:计算列 前言 本博主将用CSDN记录软件开发求学之路上亲身所得与所学的心得与知…

Dubbo sentinel 哨兵 熔断 慢调用比例、异常比例、异常数

目录 熔断报这个错误 在调用程序中检测即可 页面配置熔断,配置在 consumer 消费端 慢调用比例规则 最大rt 比例阈值 熔断时长 最小请求数 统计时长 让流量一直降低发送 异常数量 设置30个异常数 Tps 异常数量未达到30个正常运行 设置1个效果直接连续…

git bash 命令行反应慢、卡顿

1. 在Windows11的电脑上安装了git 后,鼠标右键打开git bash here,打开窗口缓慢,输入命令也慢的要死,如果安装git的时候选择在桌面创建图标,通过桌面图标打开也是一样的 2. 最简单的ls 命令,都要停顿半秒 3.…