装饰模式(Decorator Pattern)

动态给对象增加功能,从一个对象的外部来给对象添加功能,相当于改变了对象的外观,比用继承的方式更加的灵活。

允许向一个现有的对象添加新的功能,同时又不改变其结构。这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装。

这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。

优点:

  • 装饰者模式比继承灵活性,在不改变原有对象的情况下给对象扩展功能,符合开闭原则。继承关系是静态的,在编译的时候就已经决定了行为,不便于控制增加行为的方式和时机。

  • 装饰者模式可以动态使用不同的装饰类排列组合,创造出多样的行为组合。

缺点:

  • 1.装饰模式会导致设计出大量的ConcreteDecorator类,增加系统的复杂性。

  • 2.对于多次装饰的对象,一旦出现错误,排错繁琐;

应用场景:

装饰模式通常在以下几种情况使用。

  • 当需要给一个现有类添加附加职责,而又不能采用生成子类的方法进行扩充时。例如,该类被隐藏或者该类是终极类或者采用继承方式会产生大量的子类。

  • 当需要通过对现有的一组基本功能进行排列组合而产生非常多的功能时,采用继承关系很难实现,而采用装饰模式却很好实现。

  • 当对象的功能要求可以动态地添加,也可以再动态地撤销。

可大致分成三个部分:原有对象、添加职责、具体职责

通过继承关系添加职责

代码实现:

Component组成部分
public abstract class Component {public abstract void  Operation();  //实施
}Decorator装饰类
abstract class Decorator extends Component {
protected Component component; //只声明,不时例public void SetComponent(Component component){this.component = component;}@Overridepublic void Operation() {if (component != null){component.Operation();}}
}装饰模式Person类(ConcreteComponent)具体成员*/
public class Person {private String name;public Person() {}public Person(String name) {this.name = name;}public void show() {System.out.println("装扮的" + name);}
}服饰抽象类(Decorator)
public class Finery extends Person { //服饰protected Person component;//    打扮public void Decorate(Person component){this.component = component;}//    重写方法@Overridepublic void show() {
//        super.show();if (component != null){component.show();}}
}具体服饰BigTrouser
public class BigTrouser extends Finery {@Overridepublic void show() {System.out.println("大垮裤");super.show();}
}具体服饰TShirts
public class TShirts extends Finery{@Overridepublic void show() {System.out.println("大T恤");super.show();}
}具体服饰Sneakers
public class Sneakers extends Finery {@Overridepublic void show() {System.out.println("破球鞋");super.show();}
}具体服饰Suit
public class Suit extends Finery {@Overridepublic void show() {System.out.println("西装");super.show();}
}具体服饰Tie
public class Tie extends Finery {@Overridepublic void show() {System.out.println("领带");super.show();}
}具体服饰LeatherShoespublic class LeatherShoes extends Finery {@Overridepublic void show() {System.out.println("皮鞋");super.show();}
}客户端
public class Client {public static void main(String[] args) {Person xc = new Person("小蔡");System.out.println("\n第一种装扮:");TShirts dtx = new TShirts();BigTrouser kk = new BigTrouser();Sneakers pqx = new Sneakers();dtx.Decorate(xc);kk.Decorate(dtx);pqx.Decorate(kk);pqx.show();System.out.println("\n第二种装扮:");LeatherShoes px = new LeatherShoes();Tie ld = new Tie();Suit xz = new Suit();px.Decorate(xc);ld.Decorate(px);xz.Decorate(ld);xz.show();}
}

责任链(Chain of Responsibility)

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

注意:责任链模式也叫职责链模式。

在责任链模式中,客户只需要将请求发送到责任链上即可,无须关心请求的处理细节和请求的传递过程,所以责任链将请求的发送者和请求的处理者解耦了。

责任链模式是一种对象行为型模式,

其主要优点如下:

  1. 降低了对象之间的耦合度。该模式使得一个对象无须知道到底是哪一个对象处理其请求以及链的结构,发送者和接收者也无须拥有对方的明确信息。

  2. 增强了系统的可扩展性。可以根据需要增加新的请求处理类,满足开闭原则。

  3. 增强了给对象指派职责的灵活性。当工作流程发生变化,可以动态地改变链内的成员或者调动它们的次序,也可动态地新增或者删除责任。

  4. 责任链简化了对象之间的连接。每个对象只需保持一个指向其后继者的引用,不需保持其他所有处理者的引用,这避免了使用众多的 if 或者 if···else 语句。

  5. 责任分担。每个类只需要处理自己该处理的工作,不该处理的传递给下一个对象完成,明确各类的责任范围,符合类的单一职责原则。

其主要缺点如下:

  1. 不能保证每个请求一定被处理。由于一个请求没有明确的接收者,所以不能保证它一定会被处理,该请求可能一直传到链的末端都得不到处理。

  2. 对比较长的职责链,请求的处理可能涉及多个处理对象,系统性能将受到一定影响。

  3. 职责链建立的合理性要靠客户端来保证,增加了客户端的复杂性,可能会由于职责链的错误设置而导致系统出错,如可能会造成循环调用。

应用场景:

  1. 有多个对象可以处理一个请求,哪个对象处理该请求由运行时刻自动确定。

  2. 可动态指定一组对象处理请求,或添加新的处理者。

  3. 在不明确指定请求处理者的情况下,向多个处理者中的一个提交请求。

归结起来就是传递请求、处理请求

代码实现:

可以看到客户端都是“jingli”发起,但是最后输出的管理者按照职责范围层层递进,由对应管理者审批

管理者(抽象类)
abstract class Manager {protected String name;protected Manager superior;  //管理者的上级public Manager(String name) {this.name = name;}//    设置管理者的上级public void SetSuperior(Manager superior){this.superior = superior;}//    申请请求abstract public void RequestApplications(Request request);
}申请
public class Request {//    申请类别private String requestType;public String getRequestType () {return requestType;}public void setRequestType (String requestType){this.requestType = requestType;}//    申请内容private String requestContent;public String getRequestContent() {return requestContent;}public void setRequestContent(String requestContent) {this.requestContent = requestContent;}//    数量private int number;public int getNumber() {return number;}public void setNumber(int number) {this.number = number;}public Request() {}public Request(String requestType, String requestContent, int number) {this.requestType = requestType;this.requestContent = requestContent;this.number = number;}
}经理class CommonManager extends Manager{public CommonManager(String name) {super(name);}@Overridepublic void RequestApplications(Request request) {if (request.getRequestType().equals("请假") && request.getNumber() <= 2) {System.out.println(name + ": "+  request.getRequestContent()+"数量:"+request.getNumber()+" 被批准");}else {if (superior != null)  //其余申请转到上级superior.RequestApplications(request);}}}总监
class Majordomo extends Manager{public Majordomo(String name) {super(name);}@Overridepublic void RequestApplications(Request request) {if (request.getRequestType().equals("请假" ) && request.getNumber() <= 5) {System.out.println(name + ": "+  request.getRequestContent()+"数量:"+request.getNumber()+" 被批准");}else {if (superior != null)  //其余申请转到上级superior.RequestApplications(request);}}}总经理
class GeneralManager extends Manager {public GeneralManager(String name) {super(name);}@Overridepublic void RequestApplications(Request request) {if (request.getRequestType().equals("请假" ) ) {  //总经理可以准许下属任意天数的假期System.out.println(name + ": "+  request.getRequestContent()+"数量:"+request.getNumber()+" 被批准");}else if(request.getRequestType().equals("加薪") && request.getNumber() <= 500){   //总经理可以准许下属500以内加薪System.out.println(name + ": "+ request.getRequestContent()+"数量:"+request.getNumber()+" 被批准");}else if (request.getRequestType().equals("加薪") && request.getNumber() > 500){  //超过500考虑一下System.out.println(name + ": "+  request.getRequestContent()+"数量:"+request.getNumber()+" 再说吧");}}
}客户
public class Test {public static void main(String[] args) {CommonManager jinli = new CommonManager("金利");Majordomo zongjian = new Majordomo("宗剑");GeneralManager zhongjingli = new GeneralManager("钟精励");jinli.SetSuperior(zongjian);  //指定对象上级zongjian.SetSuperior(zhongjingli);Request request = new Request();request.setRequestType("请假");request.setRequestContent("小蔡请假");request.setNumber(1);jinli.RequestApplications(request);Request request2 = new Request();request2.setRequestType("请假");request2.setRequestContent("小蔡请假");request2.setNumber(4);jinli.RequestApplications(request2);Request request3 = new Request();request3.setRequestType("加薪");request3.setRequestContent("小蔡请求加薪");request3.setNumber(500);jinli.RequestApplications(request3);Request request4 = new Request();request4.setRequestType("加薪");request4.setRequestContent("小蔡请求加薪");request4.setNumber(800);jinli.RequestApplications(request4);}}

异同点:

  • 最低层都是封装继承和多态的运用
  • 装饰者模式在创建对象时是父类身份 子类对象,职责链模式在创建对象时是父类身份 父类对象,但最后穿进来都是子类对象,二者本质上并无不同
  • 职责链模式实现了请求者和处理者的松耦合。动态组合职责。比状态模式耦合度更低,更加灵活。可以随时地增加或修改处理一个请求地结构。增强了给对象指派职责地灵活性。

从装饰模式和职责链模式看链式结构模式相关推荐

  1. 设计模式 创建模式 结构模式和行为模式

    创建型模式关注对象的创建 结构型模式关注类或对象之间的组织关系 行为型模式关注类或对象间的交互和职责分配(就是用来干什么) 模式从本质上都是简化和分解类或对象,使易于扩展或封装性更好:一些相似的模式的 ...

  2. Java设计模式分为创建模式, 结构模式, 行为模式 3种类型

    Java设计模式之创建模式包括: Factory,    工厂模式 Singleton,   单例模式 Builder,    建造模式 Prototype,    原型模式 Java设计模式之结构模 ...

  3. 八、结构模式之组合(Composite)模式

    组合模式属于对象的结构模式,有时又叫做部分-整体模式,组合模式将对象组织到树结构中,可以用来描述整体与部分的联系.其可以使客户端将单纯元素和组合元素同等对待. 当需求中是体现部分与整体层次的结构时,以 ...

  4. 设计模式(三)结构型模式(四)合成模式、享元模式

    写在前面: 你好,欢迎你的阅读! 我热爱技术,热爱分享,热爱生活, 我始终相信:技术是开源的,知识是共享的! 博客里面的内容大部分均为原创,是自己日常的学习记录和总结,便于自己在后面的时间里回顾,当然 ...

  5. 商业模式新生代之免费商业模式

    这次商业模式学习比较简单,可能于实际市场还有脱节,有些例子也不是很新. 但是商业模式贵在活学活用,这次下定决心今年利用周末时间,要把<商业模式新生代>全部看完.(宏.微观经济学还是靠后吧) ...

  6. GraLSP | 考虑局部结构模式的GNN

    今天给大家介绍香港科技大学的Yilun Jin等人在AAAI 2020发表的一篇文章"GraLSP:Graph Neural Networks with Local Structural P ...

  7. 结构模式--之--享元模式

    享元模式是对象的结构模式,享元模式以共享的方式高效地支持大量的细粒度对象.享元对象能做到共享的关键区分内蕴状态和外蕴状态. 一个内蕴状态是存储在享元对象内部的,并且是不会随着环境改变而有所不同,因此, ...

  8. Java与模式学习笔记 —— 合成(Composite)模式

    合成模型模式属于对象的结构模式,又称作部分-整体(Part-Whole)模式.合成模式将对象组织到树结构中,可以用来描述整体与部分的关系.合成模式可以使客户端将单纯元素与复合元素同等看待. 一.树结构 ...

  9. 设计模式-职责链模式(责任链模式)

    职责链模式 将一系列类似却职责不全相同的对象 像链表一样 链接起来,当有一个请求,需要找能处理请求的处理对象,针对每一个请求如果都需要记住能处理它的对象是非常麻烦的,于是可以通过这条职责链,一路暴力寻 ...

最新文章

  1. TensorFlow基础10-(误差反向传播算法以及实现多层神经网络)
  2. 词法分析器的设计与实现
  3. 利用python实现简易版的贪吃蛇游戏(面向python小白)
  4. Nginx —— 检查配置文件nginx.conf的正确性命令(-t)
  5. dfs遍历和bfs遍历python_广度优先遍历(BFS)和深度优先遍历(DFS)
  6. 读《程序设计实践》之一 风格
  7. java中将字符串顺序反传转_如何在Java中将字符串序列化的Erlang术语反序列化为JInterface对象?...
  8. django中使用原生sql
  9. contentprovider java_创建Contentprovider,
  10. SAP License:后SAP ECC 6.0 时代
  11. 2016CCPC长春:Sequence II(主席树)
  12. Java 多版本JDK 环境配置 javac和java 版本不一致
  13. C#反射获取 所有字段 及 私有字段
  14. 提取win11最新等线字体1.18制作的magisk模块,有常规,加粗,和细体三个字重。
  15. 【图像算法朝圣之路二】虹膜识别1(K-means算法)
  16. 支付网关-vertx
  17. 【CVPR 2021】Unsupervised Pre-training for Person Re-identification(UPT)
  18. 笔记本电脑外接显示器以后检测不到笔记本电脑原来的显示器,把hdmi拔出来了也没用
  19. 手写基于redis实现分布式限流器-pdlr
  20. 撰写SCI论文好用的免费工具(下) - 易智编译EaseEditing

热门文章

  1. AUTOSAR FunctionalSafety
  2. 2019年6月六级第一套翻译解析
  3. 建立完善的区块链游戏新生态——HTML5区块链游戏大会在京举行
  4. 黑莓应用开发综述(转载加工基于CSDN黑莓专区)
  5. 腾讯开放平台的应用认领,问题和命令操作记录(MacOS下,Win同理)
  6. 一专一能、一专多能、多专多能 你是哪一种
  7. 简易 文章发布系统——后台管理系统
  8. java 设置pdf页面大小_通过Java实现对PDF页面的详细设置
  9. 什么是SRE,如何从 0 建设 SRE 运维体系?
  10. 中国商业智能(BI)行业市场供需与战略研究报告