行为型设计模式(二)责任链模式 策略模式

责任链模式 Chain of Responsibility

1、什么是责任链模式

责任链模式为请求创建一个接收者对象的链,每个接收者都包含对另一个接收者的引用。如果一个对象不能处理请求,它会将请求传递给链中的下一个接收者,如此模式下,请求沿着链传递,直到有一个对象能够处理它。

2、为什么使用责任链模式

  1. 解耦发送者和接收者:责任链模式允许请求的发送者和接收者解耦,发送者不需要知道请求的处理者是谁,处理者也不需要知道请求的发送者是谁。
  2. 动态添加处理者:可以动态地添加或修改处理者,灵活性较高。新的处理者可以很容易地被插入到链中。
  3. 避免请求的发送者与接收者直接耦合:责任链模式避免了直接连接发送者与接收者,降低了系统的耦合度。

3、如何使用责任链模式

设计实现一个关于请假审批的链

// 请求类
class LeaveRequest {
    private String employee;
    private int days;

    LeaveRequest(String employee, int days) {
        this.employee = employee;
        this.days = days;
    }

    String getEmployee() {
        return employee;
    }

    int getDays() {
        return days;
    }
}

// 处理者接口
interface Approver {
    void processRequest(LeaveRequest request);
}

// 具体处理者1
class Supervisor implements Approver {
    private final int MAX_LEAVES = 3;
    private Approver nextApprover;

    Supervisor(Approver nextApprover) {
        this.nextApprover = nextApprover;
    }

    @Override
    public void processRequest(LeaveRequest request) {
        if (request.getDays() <= MAX_LEAVES) {
            System.out.println("Supervisor approves leave for " + request.getEmployee() + " (" + request.getDays() + " days)");
        } else if (nextApprover != null) {
            nextApprover.processRequest(request);
        }
    }
}

// 具体处理者2
class Manager implements Approver {
    private final int MAX_LEAVES = 7;
    private Approver nextApprover;

    Manager(Approver nextApprover) {
        this.nextApprover = nextApprover;
    }

    @Override
    public void processRequest(LeaveRequest request) {
        if (request.getDays() <= MAX_LEAVES) {
            System.out.println("Manager approves leave for " + request.getEmployee() + " (" + request.getDays() + " days)");
        } else if (nextApprover != null) {
            nextApprover.processRequest(request);
        }
    }
}

// 具体处理者3
class Director implements Approver {
    private Approver nextApprover;

    Director(Approver nextApprover) {
        this.nextApprover = nextApprover;
    }

    @Override
    public void processRequest(LeaveRequest request) {
        System.out.println("Director approves leave for " + request.getEmployee() + " (" + request.getDays() + " days)");
    }
}

// 客户端代码
public class Client {
    public static void main(String[] args) {
        Approver director = new Director(null);
        Approver manager = new Manager(director);
        Approver supervisor = new Supervisor(manager);

        // 创建请假请求
        LeaveRequest request1 = new LeaveRequest("Alice", 2);
        LeaveRequest request2 = new LeaveRequest("Bob", 5);
        LeaveRequest request3 = new LeaveRequest("Charlie", 8);

        // 处理请假请求
        supervisor.processRequest(request1);
        supervisor.processRequest(request2);
        supervisor.processRequest(request3);
    }
}

4、是否存在缺陷和不足

  1. 如果责任链没有被正确配置,存在请求漏处理的风险。
  2. 链中的每个处理者都需要判断是否能够处理请求,性能上会有一些额外的开销,对性能有一定影响的风险。

5、如何缓解缺陷和不足

  1. 在责任链的末尾添加一个默认处理者,确保所有请求都能被处理。
  2. 在链中添加一些优化措施,减少不必要的判断,提高性能。

策略模式 Strategy

1、什么是策略模式

策略模式是定义一系列的算法,将每个算法封装起来,并使它们可以相互替换。策略模式使得算法的变化独立于使用算法的客户端。

2、为什么使用策略模式

  1. 算法独立性:策略模式将每个算法封装成一个策略类,使得算法可以独立于其他部分变化,提高了代码的灵活性。
  2. 易于扩展:新的算法可以很容易地添加到系统中,不需要修改已有的代码。
  3. 避免使用条件语句:策略模式消除了大量的条件语句,使得代码更加清晰和易于维护。

3、如何使用策略模式

设计实现一个简单的图像处理应用,根据用户的选择应用不同的滤镜

// 策略接口
interface FilterStrategy {
    void applyFilter(String fileName);
}

// 具体策略1:黑白滤镜
class BlackAndWhiteFilter implements FilterStrategy {
    @Override
    public void applyFilter(String fileName) {
        System.out.println("Applying Black and White filter to " + fileName);
    }
}

// 具体策略2:高对比度滤镜
class HighContrastFilter implements FilterStrategy {
    @Override
    public void applyFilter(String fileName) {
        System.out.println("Applying High Contrast filter to " + fileName);
    }
}

// 具体策略3:模糊滤镜
class BlurFilter implements FilterStrategy {
    @Override
    public void applyFilter(String fileName) {
        System.out.println("Applying Blur filter to " + fileName);
    }
}

// 上下文类,维护一个策略对象
class ImageProcessor {
    private FilterStrategy filterStrategy;

    // 设置策略对象
    void setFilterStrategy(FilterStrategy filterStrategy) {
        this.filterStrategy = filterStrategy;
    }

    // 应用滤镜
    void applyFilter(String fileName) {
        if (filterStrategy != null) {
            filterStrategy.applyFilter(fileName);
        }
    }
}

// 客户端代码
public class Client {
    public static void main(String[] args) {
        ImageProcessor imageProcessor = new ImageProcessor();

        // 应用黑白滤镜
        imageProcessor.setFilterStrategy(new BlackAndWhiteFilter());
        imageProcessor.applyFilter("image1.jpg");

        // 应用高对比度滤镜
        imageProcessor.setFilterStrategy(new HighContrastFilter());
        imageProcessor.applyFilter("image2.jpg");

        // 应用模糊滤镜
        imageProcessor.setFilterStrategy(new BlurFilter());
        imageProcessor.applyFilter("image3.jpg");
    }
}

4、是否存在缺陷和不足

  1. 在策略模式下,客户端需要直到所有的策略类,然后根据自己的场景选择合适的策略去调用执行,可能会导致策略类过多的时候而复杂度增大。

5、如何缓解缺陷和不足

  1. 可以结合工厂模式,由工厂负责创建具体的策略对象,减轻客户端的责任。
  2. 可以通过依赖注入的方式,将具体的策略对象注入到上下文类中,降低客户端的耦合度。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

机器视觉工程师,我存多少钱可以躺平

钱钱钱&#xff01;还是钱&#xff01;除了钱还能聊点别的吗&#xff1f;钱可以让你生活的更好&#xff0c;也可以让你​在生活中的选择很无奈。 如果想要知道拥有多少存款才能躺平不上班&#xff0c;那么首先要明确躺平的定义。所谓的躺平&#xff0c;其实并不代表不能工作&a…

ASP.NET Core面试题之Redis高频问题

&#x1f388;&#x1f388;在.NET后端开发岗位中&#xff0c;如今也少不了、微服务、分布式、高并发高可用相关的面试题&#x1f388;&#x1f388; &#x1f44d;&#x1f44d;本文分享一些整理的Redis高频面试题&#x1f389; &#x1f44d;&#x1f44d;机会都是给有准备…

WPF——样式和控件模板、数据绑定与校验转换

样式和控件模板 合并资源字典 Style简单样式的定义和使用 ControlTemplate控件模板的定义和使用 定义 使用 Trigger触发器 数据绑定与校验转换 数据绑定的设置 代码层实现绑定 数据模板DataTemplate xml文件的读取与显示 方法的返回值作为源绑定到控件中ObjectDataProvider L…

Axure之中继器的使用(交互动作reperter属性Item属性)

目录 一.中继器的基本使用 二.中继器的动作&#xff08;增删改查&#xff09; 2.1 新增 2.2 删除 2.3 更新行 2.4 效果展示 2.5 模糊查询 三.reperter属性 在Axure中&#xff0c;中继器&#xff08;Repeater&#xff09;是一种功能强大的组件&#xff0c;用于创建重复…

ES集群G1回收器,堆空间无法被回收问题

ES堆空间不足的问题&#xff0c;困扰了我有两年的时间。dump堆去分析&#xff0c;也未能分析出来&#xff0c;堆到底是被什么占用了。 我把堆空间给了31.9G&#xff0c;这是指针压缩生效的临界值&#xff0c;如果再大就指针压缩失效了。 痛苦的是&#xff0c;随着时间的增长。堆…

【HarmonyOS开发】ArkTs关系型和非关系型数据库的存储封装

前面使用了首选项的存储方式&#xff0c;因此将其他的两种存储方式&#xff08;键值型数据库和关系型数据库&#xff09;也学习一下&#xff0c;简单记录一下&#xff0c;并进行封装&#xff0c;方便后续使用。 1、效果预览 2、使用条件 2.1 键值型数据库 键值型数据库实现数据…

linux 应用开发笔记---【线程】

1.概念&#xff1a; 线程是参与系统调度的最小单位&#xff0c;它被包含在进程中&#xff0c;是进程的实际运行单位 一个进程可以创建多个线程&#xff0c;多个线程并发运行&#xff0c;每个线程执行不同的任务 2.如何创建线程 当一个程序启动的时候&#xff0c;一个进程被…

小鹅通基于 TSE 云原生 API 网关的落地实践

导语 2023腾讯全球数字生态大会已于9月7-8日完美落幕&#xff0c;40专场活动展示了腾讯最新的前沿技术、核心产品、解决方案。 微服务与消息队列专场&#xff0c;我们邀请到了小鹅通的基础架构组负责人黄徐震为我们带来了《小鹅通基于 TSE 云原生网关的落地实践》的精彩演讲。…

TCP 核心工作机制

TCP 的核心知识&#xff1a;如何保证传输可靠 如何提高传输效率 如何保证传输可靠&#xff1a;确认应答机制 超时重传机制 如何提高传输效率&#xff1a;滑动窗口机制、流量控制机制、延时应答机制、捎带确认机制、拥塞控制机制 可靠机制 TCP的可靠性主要是通过 确认应答 …

多门店自助点餐+外卖二合一小程序系统源码:自助点餐+外卖配送 带完整搭建教程

互联网的普及和移动支付的便捷&#xff0c;餐饮行业也在经历着数字化转型。小编来给大家介绍一款多门店自助点餐外卖二合一小程序&#xff0c;带完整的搭建教程。 以下是部分代码示例&#xff1a; 系统特色功能一览&#xff1a; 1.多门店管理&#xff1a;支持一个平台管理多个…

华为OS与麒麟OS:华为自研操作系统的对决

导言 在移动操作系统领域&#xff0c;华为OS和麒麟OS代表了华为在自主研发方面的努力。本文将深入探讨这两个操作系统的特点、竞争关系以及它们在用户体验、生态系统建设等方面的差异。 1. 背景与起源 华为OS的诞生&#xff1a; 华为OS是华为公司为应对外部环境而自主…

【音视频 | AAC】AAC音频编码详解

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; &#x1f923;本文内容&#x1f923;&a…

网络基础【网线的制作、OSI七层模型、集线器、交换机介绍、路由器的配置】

目录 一.网线的制作 1.1.网线的标准 1.2.水晶头的做法 二.OSI七层模型、集线器、交换机介绍 集线器&#xff08;Hub&#xff09;&#xff1a; 交换机&#xff08;Switch&#xff09;&#xff1a; 三.路由器的配置 3.1.使用 3.2.常用的功能介绍 1、如何管理路由器 2、家…

SVN搭建指导

环境 centos 7.9 SVN安装方式一&#xff1a;yum 1.1 http服务 至今还没有搞定网页版&#xff0c;网页版需要搭建apache http服务。遇到如下问题&#xff1a; centos - svn: Could not open the requested SVN filesystem - Stack Overflow 在试了加777权限&#xff0c;加a…

Hal深入实战/perfetto-systrace实战/SurfaceFlinger合集-安卓framework开发实战开发

背景 hi&#xff0c;粉丝朋友们&#xff1a; 大家好&#xff01; 下面来介绍一下新的framework专题halperfettosurafceflinger&#xff0c;这个专题主要就是分为3大块&#xff0c;但是彼此直接又是相互关联的。 比如surfaceflingre模块深入分析需要用到hal相关的模块&#xff…

Git报错x509: certificate signed by unknown authority

下载报错&#xff1a; Error downloading object: model-00001-of-00008.safetensors (ed3ac49): Smudge error: Error downloading model-00001-of-00008.safetensors (ed3ac4983f682a999b0e4b6f072aad294c4fd9a7e968e90835ba5c4b466d3c7c): LFS: Get https://cdn-lfs.huggin…

百度侯震宇:AI原生与大模型将从三个层面重构云计算

12月20日&#xff0c;2023百度云智大会智算大会在北京举办&#xff0c;大会以「大模型重构云计算&#xff0c;Cloud for AI」为主题&#xff0c;深度聚焦大模型引发的云计算变革。 百度智能云表示&#xff0c;为满足大模型落地需求&#xff0c;正在基于「云智一体」战略重构…

〖大前端 - 基础入门三大核心之JS篇(58)〗- 面向对象案例

说明&#xff1a;该文属于 大前端全栈架构白宝书专栏&#xff0c;目前阶段免费&#xff0c;如需要项目实战或者是体系化资源&#xff0c;文末名片加V&#xff01;作者&#xff1a;哈哥撩编程&#xff0c;十余年工作经验, 从事过全栈研发、产品经理等工作&#xff0c;目前在公司…

饥荒Mod 开发(十七):手动保存和加载,无限重生

饥荒Mod 开发(十六)&#xff1a;五格装备栏 饥荒Mod 开发(十八)&#xff1a;Mod 添加配置选项 饥荒游戏会自动保存&#xff0c;本来是一个好的机制&#xff0c;但是当角色死亡的时候存档会被删除&#xff0c;又要从头开始&#xff0c;有可能一不小心玩了很久的档就直接给整没了…

C# NPOI导出dataset----Excel绘制Chart图表

仅限XLSX 2007以后版本&#xff08;2007之前版本不支持&#xff09; 1、判断文件夹是否存在&#xff0c;不存在则创建 //Application.StartupPath当前项目根目录 if (!Directory.Exists(Application.StartupPath "\Excel")) { …