链式设计模式

链式设计模式——装饰器模式和职责链模式

 装饰模式 

定义: 指在不改变现有对象结构的情况下,动态地给该对象增加一些职责(即增加其额外功能)的模式。

结构

装饰(Decorator)模式中的角色:

  • 抽象构件(Component)角色 :定义一个抽象接口以规范准备接收附加责任的对象。
  • 具体构件(Concrete Component)角色 :实现抽象构件,通过装饰角色为其添加一些职责。
  • 抽象装饰(Decorator)角色 : 继承或实现抽象构件,并包含具体构件的实例,可以通过其子 类扩展具体构件的功能。
  • 具体装饰(ConcreteDecorator)角色 :实现抽象装饰的相关方法,并给具体构件对象添加附 加的责任

结构图

例子

以快餐店买饭有不同配菜为例

//快餐接口
public abstract class FastFood {
 private float price;
 private String desc;
 public FastFood() {
 }
 public FastFood(float price, String desc) {
 this.price = price;
 this.desc = desc;
 }
 public void setPrice(float price) {
 this.price = price;
 }
 public float getPrice() {
 return price;
 }
 public String getDesc() {
 return desc;
 }
 public void setDesc(String desc) {
 this.desc = desc;
 }
 public abstract float cost();  //获取价格
}




 //炒饭
public class FriedRice extends FastFood {
 public FriedRice() {
 super(10, "炒饭");
 }
 public float cost() {
 return getPrice();
 }
 }



 //炒面
public class FriedNoodles extends FastFood {
 public FriedNoodles() {
 super(12, "炒面");
 }
 public float cost() {
 return getPrice();
 }
 }



 //配料类
public abstract class Garnish extends FastFood {
 private FastFood fastFood;
 public FastFood getFastFood() {
 return fastFood;
 }
 public void setFastFood(FastFood fastFood) {
 this.fastFood = fastFood;
 }
 public Garnish(FastFood fastFood, float price, String desc) {
 super(price,desc);
 this.fastFood = fastFood;
 }
 }



 //鸡蛋配料
public class Egg extends Garnish {
 public Egg(FastFood fastFood) {
 super(fastFood,1,"鸡蛋");
 }
 public float cost() {
 return getPrice() + getFastFood().getPrice();
 }

    @Override
    public String getDesc() {
        return super.getDesc() + getFastFood().getDesc();
    }
 }



 //培根配料
public class Bacon extends Garnish {
    public Bacon(FastFood fastFood) {
        super(fastFood,2,"培根");
    }
    @Override
    public float cost() {
        return getPrice() + getFastFood().getPrice();
    }
    @Override
    public String getDesc() {
        return super.getDesc() + getFastFood().getDesc();
    }
 }



 //测试类
public class Client {
    public static void main(String[] args) {
        //点一份炒饭
        FastFood food = new FriedRice();
        //花费的价格
        System.out.println(food.getDesc() + " " + food.cost() + "元");
        System.out.println("========");
        //点一份加鸡蛋的炒饭
        FastFood food1 = new FriedRice();
        food1 = new Egg(food1);
        //花费的价格
        System.out.println(food1.getDesc() + " " + food1.cost() + "元");
        System.out.println("========");
        //点一份加培根的炒面
        FastFood food2 = new FriedNoodles();
        food2 = new Bacon(food2);
        //花费的价格
        System.out.println(food2.getDesc() + " " + food2.cost() + "元");
    }
 }

好处

  • 装饰模式可以带来比继承更加灵活性的扩展功能,使用更加方便,可以通过组合不同的装饰对象 来获取具有不同行为状态的多样化的结果。
  • 装饰模式比继承更具良好的扩展性,完美的遵循开闭 原则,继承是静态的附加责任,装饰者则是动态的附加责任。
  • 装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式,装饰模式可以 动态扩展一个实现类的功能

职责链模式

定义:为了避免请求发送者与多个请求处理者耦合在一起,将所有请求的处理者通过前一对 象记住其下一个对象的引用而连成一条链;当有请求发生时,可将请求沿着这条链传递,直到有对象处 理它为止。

结构

职责链模式主要包含以下角色:

  • 抽象处理者(Handler)角色:定义一个处理请求的接口,包含抽象处理方法和一个后继连接。
  • 具体处理者(Concrete Handler)角色:实现抽象处理者的处理方法,判断能否处理本次请 求,如果可以处理请求则处理,否则将该请求转给它的后继者。
  • 客户类(Client)角色:创建处理链,并向链头的具体处理者对象提交请求,它不关心处理细节 和请求的传递过程。

结构图

例子

以请假流程为例

 //请假条
public class LeaveRequest {
 private String name;//姓名
private int num;//请假天数
    private String content;//请假内容
    public LeaveRequest(String name, int num, String content) {
        this.name = name;
        this.num = num;
        this.content = content;
    }
    public String getName() {
        return name;
    }
    public int getNum() {
        return num;
    }
    public String getContent() {
        return content;
    }
 }




 //处理者抽象类
public abstract class Handler {
    protected final static int NUM_ONE = 1;
    protected final static int NUM_THREE = 3;
    protected final static int NUM_SEVEN = 7;
    //该领导处理的请假天数区间
    private int numStart;
    private int numEnd;
    //领导上面还有领导
    private Handler nextHandler;
    //设置请假天数范围 上不封顶
    public Handler(int numStart) {
        this.numStart = numStart;
    }
    //设置请假天数范围
    public Handler(int numStart, int numEnd) {
        this.numStart = numStart;
        this.numEnd = numEnd;
    }
    //设置上级领导
    public void setNextHandler(Handler nextHandler){
        this.nextHandler = nextHandler;
    }
    //提交请假条
    public final void submit(LeaveRequest leave){
        if(0 == this.numStart){
            return;
        }
        //如果请假天数达到该领导者的处理要求
        if(leave.getNum() >= this.numStart){
            this.handleLeave(leave);
            //如果还有上级 并且请假天数超过了当前领导的处理范围
            if(null != this.nextHandler && leave.getNum() > numEnd){
                this.nextHandler.submit(leave);//继续提交
            } else {
                System.out.println("流程结束");
            }
        }
    }
    //各级领导处理请假条方法
    protected abstract void handleLeave(LeaveRequest leave);
 }




 //小组长
public class GroupLeader extends Handler {
    public GroupLeader() {
        //小组长处理1-3天的请假
        super(Handler.NUM_ONE, Handler.NUM_THREE);
    }
    @Override
    protected void handleLeave(LeaveRequest leave) {
        System.out.println(leave.getName() + "请假" + leave.getNum() + 
"天," + leave.getContent() + "。");
        System.out.println("小组长审批:同意。");
    }
 }




 //部门经理
public class Manager extends Handler {
    public Manager() {
        //部门经理处理3-7天的请假
        super(Handler.NUM_THREE, Handler.NUM_SEVEN);
    }
    @Override
    protected void handleLeave(LeaveRequest leave) {
        System.out.println(leave.getName() + "请假" + leave.getNum() + 
"天," + leave.getContent() + "。");
        System.out.println("部门经理审批:同意。");
    }
 }




 //总经理
public class GeneralManager extends Handler {
    public GeneralManager() {
        //部门经理处理7天以上的请假
        super(Handler.NUM_SEVEN);
    }
    @Override
    protected void handleLeave(LeaveRequest leave) {
        System.out.println(leave.getName() + "请假" + leave.getNum() + 
"天," + leave.getContent() + "。");
        System.out.println("总经理审批:同意。");
    }

 }



 //测试类
public class Client {
 public static void main(String[] args) {
 //请假条来一张
LeaveRequest leave = new LeaveRequest("小花",5,"身体不适");
 //各位领导
GroupLeader groupLeader = new GroupLeader();
 Manager manager = new Manager();
 GeneralManager generalManager = new GeneralManager();
 groupLeader.setNextHandler(manager);//小组长的领导是部门经理
manager.setNextHandler(generalManager);//部门经理的领导是总经理
//之所以在这里设置上级领导,是因为可以根据实际需求来更改设置,如果实战中上级领
导人都是固定的,则可以移到领导实现类中。
//提交申请
groupLeader.submit(leave);
 }
 }

优点

  • 降低了对象之间的耦合度 该模式降低了请求发送者和接收者的耦合度。 增强了系统的可扩展性 可以根据需要增加新的请求处理类,满足开闭原则。
  • 增强了给对象指派职责的灵活性 当工作流程发生变化,可以动态地改变链内的成员或者修改它们的次序,也可动态地新增或者删除 责任。
  • 责任链简化了对象之间的连接 一个对象只需保持一个指向其后继者的引用,不需保持其他所有处理者的引用,这避免了使用众多 的 if 或者 if···else 语句。
  • 责任分担 每个类只需要处理自己该处理的工作,不能处理的传递给下一个对象完成,明确各类的责任范围, 符合类的单一职责原则。

缺点

  • 不能保证每个请求一定被处理。
  • 由于一个请求没有明确的接收者,所以不能保证它一定会被处理, 该请求可能一直传到链的末端都得不到处理。
  • 对比较长的职责链,请求的处理可能涉及多个处理对象,系统性能将受到一定影响。
  • 职责链建立的合理性要靠客户端来保证,增加了客户端的复杂性,可能会由于职责链的错误设置而 导致系统出错,如可能会造成循环调用。

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

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

相关文章

小红薯x-s算法最新补环境教程12-06更新(下)

在上一篇文章中已经讲了如何去定位x-s生成的位置,本篇文章就直接开始撸代码吧 如果没看过的话可以看:小红薯最新x-s算法分析12-06(x-s 56)(上)-CSDN博客 1、获取加密块代码 首先来到参数生成的位置&…

同三维TL200H2S2 2机位互动录播主机

2路HDMI(1路4K30)输入2路SDI输入4路网络摄像机输入1路USB摄像头3路互动远程网络信号解码,2路HDMI(1路4K60)输出, 音频输入:2路3.5mm立体声线路,2路凤凰头带48V幻相电源麦克风,音频输…

dell电脑开不了机怎么回事?戴尔电脑无法开机解决方法

dell戴尔电脑开不了机,这是很多使用dell电脑用户常遇到的问题。这种故障情况是由多种原因引起,包括硬件故障、软件问题或电源问题等等。dell电脑开不了机怎么办呢?下面便为大家介绍一下相关解决修复方法,帮助用户解决戴尔电脑无法…

【AI系统】Auto-Tuning 原理

Auto-Tuning 原理 在硬件平台驱动算子运行需要使用各种优化方式来提高性能,然而传统的手工编写算子库面临各种窘境,衍生出了自动生成高性能算子的的方式,称为自动调优。在本文我们首先分析传统算子库面临的挑战,之后介绍基于 TVM…

Windows电脑伪关机(快速启动模式),怎么真关机

Windows电脑在关机的时候,进入到一个伪关机的状态,也就是并没有真正的关机,但是在一些系统更新、变更了一些设置,进行重启等操作也会进入到真关机状态 这种一般是开启快速启动模式,开启了快速启动模式功能会在关机的时…

C# WPF抽奖程序

C# WPF抽奖程序 using Microsoft.Win32; using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Windows; using System.…

【智能控制】实验,基于MATLAB的模糊推理系统设计,模糊控制系统设计

关注作者了解更多 我的其他CSDN专栏 过程控制系统 工程测试技术 虚拟仪器技术 可编程控制器 工业现场总线 数字图像处理 智能控制 传感器技术 嵌入式系统 复变函数与积分变换 单片机原理 线性代数 大学物理 热工与工程流体力学 数字信号处理 光电融合集成电路…

泷羽sec:shell编程(9)不同脚本的互相调用和重定向操作

声明: 学习视频来自B站up主 泷羽sec 有兴趣的师傅可以关注一下,如涉及侵权马上删除文章,笔记只是方便各位师傅的学习和探讨,文章所提到的网站以及内容,只做学习交流,其他均与本人以及泷羽sec团队无关&#…

记事本建java及java命名规范

1.桌面开发:c# 2. 记事本建java: 以class的名称(类名)为名,名称.java 编译jdk:javac 名称.java 调动运行jre : java 名称 查看名称.java里面的内容:cat 名称.java java 的命名规范 大驼峰(每个单词首…

数据结构---队列(Queue)

1. 简介 队列(Queue)是一种常用的数据结构,它遵循先进先出(FIFO,First In First Out)的原则。这意味着第一个进入队列的元素将是第一个被移除的元素。队列在计算机科学中有着广泛的应用,比如任…

3D 生成重建016-SA3D从nerf中分割一切

3D 生成重建016-SA3D从nerf中分割一切 文章目录 0 论文工作1 方法介绍2 实验结果 0 论文工作 1 SAM的背景和目标: SAM 是一种强大的二维视觉基础模型,能够在 2D 图像中进行任意物体的分割。传统上,SAM 在二维空间表现出色,但其无…

Ubuntu环境安装RabbitMQ

1.安装Erlang RabbitMq需要Erlang语⾔的⽀持,在安装rabbitMq之前需要安装erlang # 更新软件包 sudo apt-get update # 安装 erlang sudo apt-get install erlang 查看erlang版本 : erl 退出命令:halt(). 2. 安装RabbitMQ # 更新软件包 sudo apt-get update # 安装 …

FSWIND脉动风-风载时程生成器软件原理

大量风的实测资料表明,在风的时程曲线中,瞬时风速包含两个部分:一部分是自振周期一般在 10 分钟以上的平均风,另一部分是周期一般只有几秒左右的脉动风。平均风由于其周期一般比结构的自振周期大,因而考虑其作用性质相…

【JavaWeb后端学习笔记】MySQL的数据查询语言(Data Query Language,DQL)

MySQL DQL 1、DQL语法与数据准备1.1 DQL语法1.2 数据准备 2、基础查询2.1 查询指定字段2.2 查询返回所有字段2.3 给查询结果起别名2.4 去除重复记录 3、条件查询3.1 条件查询语法3.2 条件查询案例分析 4、分组查询4.1 分组查询语法4.2 分组查询案例分析 5、排序查询5.1 排序查询…

优化工业应用的振动筛

了解如何使用 Ansys Rocky 优化振动筛性能。 振动筛 振动筛在许多散装物料处理过程中发挥着重要作用,可实现有效的颗粒分离和分类。 它们在采矿、采石、建筑、回收和食品加工行业尤为常见。它们的设计和操作需要仔细考虑材料特性、工艺要求和环境因素,…

git修改某次commit(白痴版)

第一步 在bash窗口运行 git rebase --interactive commitId^ 比如要改的commitId是 abcedf git rebase --interactive abcedf^键盘 按 i 或者 ins 进入编辑状态 进入insert 编辑状态 在bash窗口手动把对应commit前面的pick改为e或edit 按 esc 进入退出程序 输入 :wq 保存退出…

基于 RNN(GRU, LSTM)+CNN 的红点位置检测(pytorch)

文章目录 1 项目背景2 数据集3 思路4 实验结果5 代码 1 项目背景 需要在图片精确识别三跟红线所在的位置,并输出这三个像素的位置。 其中,每跟红线占据不止一个像素,并且像素颜色也并不是饱和度和亮度极高的红黑配色,每个红线放大…

word如何快速创建目录?

文章目录 1,先自己写出目录的各级标题。2、选中目标标题,然后给它们编号3、给标题按照个人需求开始分级4、插入域构建目录。4.1、利用快捷键插入域构建目录4.2、手动插入域构建目录 听懂掌声!学会了吗? 前提声明:我在此…

【金猿CIO展】复旦大学附属中山医院计算机网络中心副主任张俊钦:推进数据安全风险评估,防范化解数据安全风险,筑牢医疗数据安全防线...

‍ 张俊钦 本文由复旦大学附属中山医院计算机网络中心副主任张俊钦撰写并投递参与“数据猿年度金猿策划活动——2024大数据产业年度优秀CIO榜单及奖项”评选。 大数据产业创新服务媒体 ——聚焦数据 改变商业 数据要素时代,医疗数据已成为医院运营与决策的重要基石…

【工具变量】上市公司企业劳动密集度数据(2008-2023年)

一、测算方式: 参考《数量经济技术经济研究》陈勇兵(2023)老师的做法,使用员工数量与销售收入的比值作为劳动密集度的度量标准* o/ b% C( e* U我们做的比他完善,分为四类大家可以做核心变量或者稳健性检验Labor1&…