『设计模式』小伙你的穿搭很潮!--装饰者模式
23种设计模式+额外常用设计模式汇总 (持续更新)
装饰模式(Decorator):又名包装模式。装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案。
装饰模式常常被称为包裹模式,就是因为每一个具体装饰类都将下一个具体装饰类或者具体构成类包裹起来。
包含角色
- 抽象构成(Component)角色
给出一个抽象接口,以规范准备接收附加责任的对象。 - 具体构成(Concrete Component)角色
实现组件对象接口,通常就是被装饰器装饰的对象。 - 装饰(Decorator)角色
持有一个构件(Component)对象的实例,并定义一个与抽象构件接口一致的接口。 - 具体装饰(Concrete Decorator)角色
负责给构件对象“贴上”附加的责任
特点
- 装饰模式为对象添加额外责任的方式就像做蛋糕一样,一圈一圈的加上去,中间的面包是核心,是被装饰的对象,是核心任务,外围的都是装饰对象。
- 这就是说装饰模式包含两部分内容,即装饰独享和被装饰对象。
- 按照GOF的说法,Decorator模式的意图是:动态的给一个对象添加一些额外的职责。就增加功能来说,Decorator模式相比生成子类更为灵活。
- 这个被装饰的对象不一定是最原始的那个对象,也可能是被其他装饰器装饰过的对象,反正都是实现的同一接口,也就是同一类型。
- Decorator模式的效果是:让我们可以创建以decorator对象——负责新的功能的对象——开始的一条对象“链”,并接受与租出的对象。
Decorator链
Decorator1->Decorator2->Decorator3->Concrete Comp
模式讲解
功能
能够实现动态地为对象添加功能,是从一个对象外部来给对象增加功能,相当一是改变了对象的外观
对象组合
Favor Composition Over Inheritance
装饰器和组件类的关系
装饰器是用来装饰组件类的关系,装饰器一定要实现和组件类一致的接口,保证他们是同一个类型,并且具有同一个外观这样组合完成的装饰才能够递归调用下去。
本质
动态是手段,组合是目的
优点
- 装饰模式与集成关系的目的都是要扩展对象的功能,但是装饰模式可以提供比继承更多的灵活性。
- 通过使用不同的具体装饰类似以及这些装饰类的排列组合,设计师可以创造出很多不同行为的组合。
缺点
会产生很多细粒度对象
装饰模式与策略模式
- 策略模式改变的是对象的内核
- 装饰模式改变的是对象的外壳
- 策略模式是一层调用
- 装饰模式是递归调用
- 可以有机结合
装饰模式与AOP
- APO(Aspect Qriented Programming)是OOP的延续,意思是面向方面编程。
- 面向对象开发中,烤炉系统的角度通常是纵向的。
- AOP的主要的功能是:日志记录,性能统计,安全控制,事务处理,异常处理等等。
- 主要意图是:将日志记录,性能统计,安全控制,事务处理,异常处理等代码从业务员逻辑代码中划分出来,通过对这些行为的分离,我们希望可以将他们独立到非知道业务逻辑的方法中,进而改变这些行业的时候不影响业务逻辑的代码。
举例
实现
//抽象构件(Component)角色
public abstract class Component {public abstract void operate();//具体构件(ConcreteComponent)角色,被包装对象
public class ConcreteComponent extends Component {@Overridepublic void operate() {System.out.println("ConcreteComponent 原始对象操作");}
}
// 装饰(Decorator)角色:
public abstract class Decorator extends Component {private Component component;/*** 构造函数传递要装饰的对象* @param component 被装饰的对象*/public Decorator(Component component) {this.component = component;}@Overridepublic void operate() {//调用被装饰者的方法this.component.operate();}
}public class ConcreteDecoratorA extends Decorator {public ConcreteDecoratorA(Component component) {super(component);}@Overridepublic void operate() {super.operate();//调用自己的方法this.operateAMethod();}private void operateAMethod() {System.out.println("ConcreteDecoratorA添加的修饰方法");}
}public class ConcreteDecoratorB extends Decorator {public ConcreteDecoratorB(Component component) {super(component);}@Overridepublic void operate() {//调用自己的方法this.operateBMethod();super.operate();}private void operateBMethod() {System.out.println("ConcreteDecoratorB添加的修饰方法");}
}public class Client {public static void main(String[] args) {//创建原始对象Component component = new ConcreteComponent();//第一次装饰component = new ConcreteDecoratorA(component);//第二次装饰component = new ConcreteDecoratorB(component);//两次装饰后的操作component.operate();}
}
【问题】 一个人可以搭配不同的服饰:例如,大T恤,垮裤,破球鞋;或者,西装,领带,皮鞋。
【装饰模式实现代码】
using System;
namespace Wear
{abstract class Component{public abstract void Show();}class Person: Component{private String name;public Person() { }public Person(String name){this.name = name;}public override void Show(){Console.WriteLine("装饰的{0}", name);}}class Finery : Component{protected Component component;public Finery(Component component){this.component = component;}public override void Show(){if(component!=null){component.Show();}}}class Tshirt:Finery{public Tshirt(Component component) : base(component) { }public override void Show(){Console.Write("大T恤 ");base.Show();}}class BigTrouser : Finery{public BigTrouser(Component component) : base(component) { }public override void Show(){Console.Write("垮裤 ");base.Show();}}class Sneakers : Finery{public Sneakers(Component component) : base(component) { }public override void Show(){Console.Write("破球鞋 ");base.Show();}}class Suit : Finery{public Suit(Component component) : base(component) { }public override void Show(){Console.Write("西装 ");base.Show();}}class Tie : Finery{public Tie(Component component) : base(component) { }public override void Show(){Console.Write("领带 ");base.Show();}}class LeatherShoes : Finery{public LeatherShoes(Component component) : base(component) { }public override void Show(){Console.Write("皮鞋 ");base.Show();}}class Program{static void Main(string[] args){Person xc = new Person("小菜");Console.WriteLine("第一种装扮");Finery dtx = new Tshirt(new BigTrouser(new Sneakers(xc)));dtx.Show();Console.WriteLine("第二种装扮");Finery sut = new Suit(new Tie(new LeatherShoes(xc)));sut.Show();}}
}
【UML图】
『设计模式』小伙你的穿搭很潮!--装饰者模式相关推荐
- 『设计模式』大话西游的移魂大法竟移出来了桥接模式
23种设计模式+额外常用设计模式汇总 (持续更新) 大话西游里有那么一幕,牛魔王的妹妹使用移魂大法,使几个人的灵魂交换.我们考虑一个问题,一个哲学问题,到底他们时灵魂发生了转移,还是肉体发生了转移.到 ...
- 『设计模式』HR问了我朋友什么是简单工厂模式,竟被质疑是否学过设计模式,是否是计算机专业?
23种设计模式+额外常用设计模式汇总 (持续更新)越是简单的东西,越是容易被忽略,我来带你们好复习一下! 简单工厂模式 简单工厂模式也被称为静态工厂模式;使用简单工厂模式可以将产品的"消费& ...
- 『设计模式』之小试牛刀
为了更好的学习设计模式,以及督促自己完成设计模式的学习,现提笔为记. 怎么的,每周至少也要学一个设计模式!!! 恳请大家的监督和不吝赐教,共同学习和进步! 内容主要参考自<设计模式之禅>以 ...
- 『设计模式』HR:不会设计模式,你好意思来面试?(面试必备设计模式)
23种设计模式+额外常用设计模式汇总 (持续更新) 设计模式(Design pattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用.设计模式是软件开发人员在软件开发过程中面临的一 ...
- 『设计模式』不看就亏了的设计模式总结
23种设计模式+额外常用设计模式汇总 (持续更新) 设计模式(Design pattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用.设计模式是软件开发人员在软件开发过程中面临的一 ...
- 『设计模式』工厂方法模式
23种设计模式+额外常用设计模式汇总 (持续更新) 工厂方法(Factory Method)模式 工厂方法模式是类的创建模式,其用意是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类中. 在工 ...
- 【源码分析设计模式 5】Java I/O系统中的装饰器模式
一.基本介绍 动态地将责任附加到对象上.若要扩展功能,装饰者提供了比继承更有弹性的替代方案. 二.装饰器模式的结构 1.Component,抽象构件 Component是一个接口或者抽象类,是定义我们 ...
- 设计模式【8】-- 手工耿教我写装饰器模式
装饰器模式 前面学习了好几种设计模式,今天继续- 装饰器模式,属于结构型模式,用来包裹封装现在的类对象,希望可以在不修改现在类对象和类定义的前提下,能够拓展对象的功能. 调用的时候,使用的是装饰后的对 ...
- 『设计模式』适配器模式(Adapter)
23种设计模式+额外常用设计模式汇总 (持续更新) 适配器模式(Adapter) 适配器模式把一一个类的接口变换成客户端所期待的另一种接口,从而使原本接口不匹配而无法在一起工作的两个类能够在一起工作. ...
最新文章
- 八皇后问题 (递归 搜索)
- 刚安装了Fedora 33,尝尝鲜~,哈哈~~~
- Qt与OpenCV编程:在子线程打开摄像头用主线程显示
- 神策数据王磊:如何用 JS 实现页面录制与回放
- Github标星66.6k+:常见数据结构与算法的Python实现
- 技术总监谈好的程序员如何写代码
- 为什么我学了6个月Python,还是找不到工作?
- 从零开始学PowerShell(5)自定义格式化信息
- python中的作用域_python 模块的作用域
- 创建jenkins任务
- Windows下的网络编程
- java的swing案例
- 网络知识之----http七层协议
- ubuntu20.04安装opencv4
- 【ADRC/Matlab实现】非线性状态误差反馈NLSEF
- 计算机系统原理,实验三:bomblab,汇编详解
- 技术牛人如何发财致富?
- 自由职业者:提高效率的6个简单方法
- Intel Composer XE
- 阿里云服务器更换Ubuntu操作系统并配置图形界面