设计模式 装饰模式(Decorator)
设计模式 装饰模式(Decorator)
@author ixenos
装饰模式是什么
1.装饰模式以对客户端透明的方式对象的功能,是继承关系的一个替代方案,但装饰模式可以在不创造更多子类的情况下,对对象的功能进行扩展。
2.装饰模式以对客户端透明的方式动态地给一个对象附上更多的责任。换言之,客户端并不会觉得对象在装饰前后有什么不同。
3.装饰模式把对客户端的调用委派到被装饰类,而功能的增强在装饰类进行,装饰模式的关键在于这种扩展是完全透明的。
例如IO中的过滤流,具体就是BufferedInputStream的构造器接受一个节点流,而相关操作底层调用节点流的操作。
4.装饰模式是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。
5.本质上,利用了的接口的多态性
装饰模式的特点
1.装饰对象和真实对象具有相同的接口,这样客户端就可以以和真实对象相同的方式与装饰对象进行交互;
2.装饰对象包含一个真实对象的引用;
3.装饰对象接受来自客户端的请求,它把这些请求转发给真实对象;
4.装饰对象可以在转发这些请求之前或之后增加一些附加功能;
这样就确保了在运行时不用修改给定对象的结构就可以增加对象的功能,在面向对象设计中通常使用继承对类的功能进行扩展
装饰模式的角色
抽象构件角色(Component):(如InputStream)给出一个抽象接口,作为共同接口,以规范接收附加责任的对象。
具体构件角色(Concrete Component):(如FileInputStream)定义一个将要被附加责任的类,真实角色。
装饰角色(Decorator):(如FilterInputStream)持有一个构件对象的引用,并定义一个与抽象构件接口一致的接口。
具体装饰角色(Concrete Decorator):(如BufferedInputStream)负责给构件对象附加责任。
抽象构件角色:
public interface Component{
public void doSomeThing();
}
具体构件角色:
public class ConcreteComponent implements Component{
@Override
public void doSomeThing(){
System.out.println("功能A");
}
}
装饰角色:
/*
一、实现构件接口
二、内部持有构件变量,用以接受构件从而进行装饰
三、以此建立了一个装饰器,由装饰器子类来拓展功能
*/
public class Decorator implements Component{
private Component component; public Decorator(Component component){
this.component = component;
} /*借由真实构件来调用*/
@Override
public void doSomeThing(){
component.doSomeThing();
}
}
具体装饰角色:
/*
通过继承包装着构件的装饰器,另外添加功能; 而这对客户端来说是透明的,因为客户端把请求提交给构件,
产出也是构件产出,装饰器顺道唤醒了其他操作,
而这些操作可以用以优化处理过程或者增加额外的功能,
比如BufferedInputStream、DataInputStream等 */ public class ConcreteDecorator1 extends Decorator{
public ConcreteDecorator1(Component component){
super(component);
} @Override
public void doSomeThing(){
super.doSomeThing();
//功能增加
this.doAnotherThing();
} private void doAnotherThing(){
System.out.println("功能B");
}
}
另一个具体装饰角色:
1 public class ConcreteDecorator2 extends Decorator{
public ConcreteDecorator2(Component component){
super(component);
}
@Override
public void doSomeThing(){
super.doSomeThing();
//功能增加
this.doAnotherThing();
}
private void doAnotherThing(){
System.out.println("功能C");
}
}
客户端:
public Client{
public static void main(String[] args){
Component component = new ConcreteComponent();
Component component1 = new ConcreteDecorator1(component);
component1.doSomeThing();
//又包装一层
Component component3 = new ConcreteDecorator2(conponent1);
component2.doSoneThing();
/*或者直接用匿名对象直接多层包装,这是IO常用的做法*/
Component component3 = new ConcreteDecorator2(new ConcreteDecorator1(new ConcreteComponent()));
component3.doSomeThing();
}
}
装饰模式对比继承
- 装饰模式
- 用来扩展特定对象的功能
- 动态,运行时分配职责
- 不需要生成特定对象的子类,装饰对象相当于具有复用性的工具
- 继承
- 用来扩展一类对象的功能
- 静态,编译时分配职责
- 需要生成大量对应功能的子类,不可复用
装饰模式之于流的嵌套
流的嵌套从装饰模式的角度来说过滤流之间是无所谓顺序的,但考虑到具体应用,执行格式化输出的流在外层,缓冲流在中间是坠吼滴(缓冲流可以普通输出!)!
装饰模式的要求是:具体装饰对象给具体构件对象附加功能(注意是对象),要求扩展对象功能的同时,对客户端透明,这就需要具体装饰角色转发调用请求给具体构件角色,而具体装饰角色在转发的过程中可以对其进行扩展。具体到流就是过滤流内部维护一个从构造器接受的节点流,而各基本方法可以添加缓冲,再在合适的时候释放流,而且更可增加一些额外的功能。
设计模式 装饰模式(Decorator)的更多相关文章
- 设计模式-装饰模式(Decorator Pattern)
装饰模式(Decorator Pattern):动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活
- [工作中的设计模式]装饰模式decorator
一.模式解析 装饰模式又名包装(Wrapper)模式.装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案. 装饰模式的要点主要是: 1.需要对已有对象扩展新的功能,又不希望改变原有对 ...
- 设计模式——装饰模式(Decorator Pattern)
装饰模式:动态的给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活. UML图: 模型类: Component类: package com.cnblog.clarck; /** ...
- 乐在其中设计模式(C#) - 装饰模式(Decorator Pattern)
原文:乐在其中设计模式(C#) - 装饰模式(Decorator Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 装饰模式(Decorator Pattern) 作者:weba ...
- 设计模式系列之装饰模式(Decorator Pattern)——扩展系统功能
说明:设计模式系列文章是读刘伟所著<设计模式的艺术之道(软件开发人员内功修炼之道)>一书的阅读笔记.个人感觉这本书讲的不错,有兴趣推荐读一读.详细内容也可以看看此书作者的博客https:/ ...
- 深入浅出设计模式——装饰模式(Decorator Pattern)
模式动机 一般有两种方式可以实现给一个类或对象增加行为: 继承机制,使用继承机制是给现有类添加功能的一种有效途径,通过继承一个现有类可以使得子类在拥有自身方法的同时还拥有父类的方法.但是这种方法是静 ...
- 二十四种设计模式:装饰模式(Decorator Pattern)
装饰模式(Decorator Pattern) 介绍动态地给一个对象添加一些额外的职责.就扩展功能而言,它比生成子类方式更为灵活.示例有一个Message实体类,某个对象对它的操作有Insert()和 ...
- 设计模式-09装饰模式(Decorator Pattern)
1.模式动机 一般有两种方式可以实现给一个类或对象增加行为: 继承机制:使用继承机制是给现有类添加功能的一种有效途径,通过继承一个现有类可以使得子类在拥有自身方法的同时还拥有父类的方法.但是这种方法是 ...
- 装饰模式decorator
C++设计模式——装饰模式 前言 在实际开发时,你有没有碰到过这种问题:开发一个类,封装了一个对象的核心操作,而这些操作就是客户使用该类时都会去调用的操作:而有一些非核心的操作,可能会使用,也可能不会 ...
随机推荐
- HDU 3361 ASCII
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission ...
- 借助OpenOffice实现office转pdf(Java)的.exe小程序
原料:OpenOffice4.1.2(之所以选OpenOffice是因为可以跨平台,下载后直接安装),jodconverter-core-3.0-beta-4-dist.zip(可以搜博客园),Exe ...
- minSdkVersion与targetSdkVersion
targetSdkVersion是Android提供向前兼容的主要依据,在应用的targetSdkVersion没有更新之前,系统不会应用最新的行为变化 比如设置了app的targetSdkVersi ...
- SpringMVC Memcached 搭建WEB项目缓存框架
最近做的项目一直在使用memcached作为缓存来缓存各种数据,现在BOSS要在项目上加上缓存.并把任务交给我.便琢磨怎么解决这个问题. 看了很多文章,写的比较详尽靠谱的就是这篇了http://www ...
- maven项目如何引用本地的jar包
下载该jar包到本地(如下载目录结构为:D:\Users\lu.wang\Downloads\searchservice\searchservice\jar\ttd.search.searchserv ...
- wpf 寻找某个控件下的子控件
/// <summary> /// 寻找某个控件下的子控件 /// </summary> /// <typeparam name="ChildType" ...
- Spring in Action --- 第二章 装配Bean
Spirng配置的可选方案 在XML中进行显示配置 在Java中进行显示配置 隐式的bean发现机制和自动装配 bean装配 1. 在希望被扫描到的类上加注解 @Component 2. 基于不同的配 ...
- "malloc: * error for object 0x17415d0c0: Invalid pointer dequeued from free list * set a breakpoint in malloc_error_break to debug";
I've fixed this error with Xcode 8 on iOS 8.3. I've just changed Deployment Target from 8.3 to 8.0. ...
- SpringMVC 学习-异常处理 SimpleMappingExceptionResolver 类
Spring3.0 对异常的处理方式总共有两种: 一种是使用 HandlerExceptionResolver 接口,并且 Spring 已经提供默认的实现类 SimpleMappingExcepti ...
- RSA算法记录----摘抄
RSA算法原理(一) "公钥加密算法". 因为它是计算机通信安全的基石,保证了加密数据不会被破解.你可以想象一下,信用卡交易被破解的后果. 进入正题之前,我先简单介绍一下,什么 ...