【装饰者模式】Decorator Pattern
装饰者模式,这个模式说我一直记忆深刻的模式,因为Java的IO,我以前总觉得Java的IO是一个类爆炸,自从明白了装饰者模式,Java的IO体系让我觉得非常的可爱,我们现在看看什么是装饰者,然后再来看如何去很爽的运用Java的IO(C#的IO则不同)

Component:这个是抽象接口(这里的接口的意思不是interface关键字对应的接口,而是一个对应的口),以规范准备接收附加责任的对象。
Concrete Component:具体的组件,这个可以接收附加责任(装饰)的类
Decorator:装饰的抽象接口,实现一个与抽象构件接口一致的接口。
ConcreteDecorator:具体装饰类,负责给具体组件加上装饰的。
(每次想这个,我都觉得好抽象,不管那么多,了解一下就好,先看例子再回来看)
我们直接来弄一个,软饮(吃,这个东西最好做这个模式了)。
我们有[软饮]是一个抽象存在的东西,所以肯定是我们的抽象组件
public abstract class BeverageComponent
{ public abstract string GetDescription(); public abstract double Cost();
}
有了抽象组建,我们来想想有那些具体的组建,咖啡(Espresso),House Blend(星巴克的首选咖啡,我喜欢,大家可以试试)
我们来建立这两个类:
public class Espresso : BeverageComponent
{
public override string GetDescription()
{
return "Espresso";
} public override double Cost()
{
return ;
}
} public class HouseBlend : BeverageComponent
{
public override string GetDescription()
{
return "HouseBlend";
} public override double Cost()
{
return ;
}
}
我们为descrption字段赋值上组建的名字,然后实现了抽象方法Cost,返回自己的价格。
到这里我们拥有了抽象组建和具体组建,我们现在来构建一下抽象装饰类
public abstract class BeverageDecorator : BeverageComponent
{
//类里面虽然什么都没有,但是我们可以在这里添加一些专门属于装饰类的抽象方法.
}
我们从UML图上面看还是继承了抽象组件,有了抽象的装饰类,我们来构建一下具体的装饰类
public class Milk : BeverageDecorator
{
private BeverageComponent _beverage;
public Milk(BeverageComponent beverage)
{
_beverage = beverage;
}
public override string GetDescription()
{
return _beverage.GetDescription() + "+Milk";
} public override double Cost()
{
return _beverage.Cost() + ;
}
} public class Sugar : BeverageDecorator
{
private BeverageComponent _beverage;
public Sugar(BeverageComponent beverage)
{
_beverage = beverage;
}
public override string GetDescription()
{
return _beverage.GetDescription() + "+Sugar";
} public override double Cost()
{
return _beverage.Cost() + ;
}
}
我们构建了Sugar和Milk两个装饰类,里面带有一个又参构造并要求传入抽象组件的对象,这里说装饰者模式的核心,为什么要求传入一个抽象组件的对象呢?
这里可以传入具体组件的对象和装饰类的对象,而且当你传入了具体组件以后就不能够继续传入其他的装饰和组件了。关键的地方!!!
我们也就是可以认为,具体组件要做的是功能或者主要的东西,装饰的东西对于具体组件是可有可无的,是用于做辅助的。我们来看看一杯加糖的牛奶的咖啡怎么来。
class Program
{
static void Main(string[] args)
{
var beveage = new Milk(new Sugar(new Espresso())); Console.WriteLine("Descripiton:" + beveage.GetDescription());
Console.WriteLine("Cost:" + beveage.Cost()); Console.ReadLine();
}
}
我们先创建一个牛奶对象,在传入糖,最后把我们要的实物写进去,来看下输出。
输出为:
到这里,装饰者模式就结束了。
我们来谈谈它的应用场景:
如果你有许多的功能,并且有许多的辅助功能去辅助你这些具体功能,可以用装饰者模式。
优点:
缺点:
Java的IO

这张图说JAVA的API,我们的Component说InputStream. 除了我用红笔圈出来的都说具体组建。我们走到FilterInputStream里面看看

继承了FilterInputStream的所有类都是装饰类,所以FilterInputStream是抽象装饰类。
也就是说继承FilterInputStream这些类主要说为了辅助那些直接继承了InputStream的具体组件类(Reader,Writer,OutputStream都说这样的)
我们现在知道怎么用了把
Stream stream=new BufferedInputStream(new FileInputStream()); 这样我们主要功能说读文件,只不过在这个基础上面加了一层缓存。如果你要其他的辅助可以直接加进去,是不是很方便。
【装饰者模式】Decorator Pattern的更多相关文章
- 浅谈设计模式--装饰者模式(Decorator Pattern)
挖了设计模式这个坑,得继续填上.继续设计模式之路.这次讨论的模式,是 装饰者模式(Decorator Pattern) 装饰者模式,有时也叫包装者(Wrapper),主要用于静态或动态地为一个特定的对 ...
- 设计模式 - 装饰者模式(Decorator Pattern) Java的IO类 用法
装饰者模式(Decorator Pattern) Java的IO类 用法 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26716 ...
- 设计模式 - 装饰者模式(Decorator Pattern) 具体解释
装饰者模式(Decorator Pattern) 具体解释 本文地址: http://blog.csdn.net/caroline_wendy/article/details/26707033 装饰者 ...
- 设计模式学习--装饰者模式(Decorator Pattern)
概念: 装饰者模式(Decorator Pattern): 动态地将功能添加到对象,相比生成子类更灵活,更富有弹性. 解决方案: 装饰者模式的重点是对象的类型,装饰者对象必须有着相同的接口,也也就是有 ...
- 设计模式(三):“花瓶+鲜花”中的装饰者模式(Decorator Pattern)
在前两篇博客中详细的介绍了"策略模式"和“观察者模式”,今天我们就通过花瓶与鲜花的例子来类比一下“装饰模式”(Decorator Pattern).在“装饰模式”中很好的提现了开放 ...
- C#设计模式之装饰者模式(Decorator Pattern)
1.概述 装饰者模式,英文名叫做Decorator Pattern.装饰模式是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能.它是通过创建一个包装对象,也就是装饰来包裹真实的对象. 2 ...
- 23种设计模式之装饰器模式(Decorator Pattern)
装饰器模式(Decorator Pattern) 允许向一个现有的对象添加新的功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装. 这种模式创建了一个装饰类,用来包 ...
- 七个结构模式之装饰者模式(Decorator Pattern)
定义: 使用组合的方法,动态给一个类增加一些额外的功能,避免因为使用子类继承而导致类继承结构复杂.并且可以保持和被装饰者同一个抽象接口,从而使客户端透明. 结构图: Component:抽象构件类,定 ...
- C#设计模式——装饰者模式(Decorator Pattern)
一.例子在软件开发中,我们往往会想要给某一类对象增加不同的功能.比如要给汽车增加ESP.天窗或者定速巡航.如果利用继承来实现,就需要定义无数的类,Car,ESPCar,CCSCar,SunRoofCa ...
- 9.装饰者模式(Decorator Pattern)
using System; namespace ConsoleApplication7 { class Program { static void Main(string[] args) { // 我 ...
随机推荐
- day-9心得
操作系统发展史 手工操作(无操作系统) 1946年第一台计算机诞生--20世纪50年代中期,还未出现操作系统,计算机工作采用手工操作方式. 手工操作程序员将对应于程序和数据的已穿孔的纸带(或卡片)装入 ...
- Mellanox infinoband RDMA SDP
IPoIB Internet Protocol over InfiniBand 就是指利用物理IB网络(IB卡,线缆,交换机,更甚者IB3层交换)通过ip协议进行连接,并进行数据传输! SDP Soc ...
- RPC通信
@version: @author: morgana @license: Apache Licence @contact: vipmorgana@gmail.com @site: @software: ...
- node全局变量process属性值(mac环境)
任意新建一个js文件,只需一行代码: console.dir(process); 保存该文件后执行,即可得到process变量的属性值列表: { title: 'node', version: 'v0 ...
- Java知识总结----队列的使用
首先我们要知道使用队列的目的是什么?一般情况下,如果是一些及时消息的处理,并且处理时间很短的情况下是不需要使用队列的,直接阻塞式的方法调用就可以了.但是,如果在消息处理的时候特别费时间,这个时候如果有 ...
- c# var的含义与用法
VAR 是3.5新出的一个定义变量的类型其实也就是弱化类型的定义VAR可代替任何类型编译器会根据上下文来判断你到底是想用什么类型的至于什么情况下用到VAR 我想就是你无法确定自己将用的是什么类型就可以 ...
- delphi 浮点 精度
double 没有问题, Single有问题 '0.7' 0.69999999999999996 Single; // 4 byte real Double; // 8 byte real
- js 的 defer 和async属性
添加defer延迟属性,脚本将立即下载,但会延迟到整个页面解析完毕后按顺序执行.会先于DOMContentLoaded事件执行. 添加async异步属性,脚本将立即下载,执行时不会等待其他脚本,不一定 ...
- LUA 环境
LUA中环境是指一个函数执行的表,即一个函数在什么表中执行. 这里的函数是特殊的,是loadfile("x.lua")的返回值. loadfile("x.lua" ...
- <转> win7下破解已安装的VS2008
http://renfan.blog.51cto.com/3466724/754301 在win7系统下,已安装的VS2008维护界面是不显示序列号输入的,需要按以下步骤进行才能破解 1.点击“卸载/ ...