【装饰者模式】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) { // 我 ...
随机推荐
- 【源码阅读】Java集合之三 - ArrayDeque源码深度解读
Java 源码阅读的第一步是Collection框架源码,这也是面试基础中的基础: 针对Collection的源码阅读写一个系列的文章,本文是第三篇ArrayDeque. ---@pdai JDK版本 ...
- 跟我学算法-tensorflow 实现线性拟合
TensorFlow™ 是一个开放源代码软件库,用于进行高性能数值计算.借助其灵活的架构,用户可以轻松地将计算工作部署到多种平台(CPU.GPU.TPU)和设备(桌面设备.服务器集群.移动设备.边缘设 ...
- 【转】RocketMQ事务消费和顺序消费详解
RocketMQ事务消费和顺序消费详解 转载说明:该文章纯转载,若有侵权或给原作者造成不便望告知,仅供学习参考. 一.RocketMq有3中消息类型 1.普通消费 2. 顺序消费 3.事务消费 顺序消 ...
- python算法之归并排序
归并排序 归并排序是采用分治法的一个非常典型的应用.归并排序的思想就是先递归分解数组,再合并数组. 将数组分解最小之后,然后合并两个有序数组,基本思路是比较两个数组的最前面的数,谁小就先取谁,取了后相 ...
- Volatile关键字以及线程的内存可见性问题
一.Volatile关键字 作用: 当多个线程进行操作共享数据时,可以保证内存中的数据可见,即为一个线程对数据的修改对另外一个线程来说是可见的.相较于 synchronized 是一种较为轻量级的同步 ...
- springmvc 下载excel
jsp: controller:
- 获取web.xml配置文件中的初始化值
TestServletConfig.java package com.huawei.config; import java.io.IOException;import java.util.Enumer ...
- GLSL in ShaderLab
[Syntax] However, use of raw GLSL is only recommended for testing, or when you know you will only ta ...
- Nginx 源码完全注释(11)ngx_spinlock
Nginx 是多进程模式的,一个 master 与多个 workers,一般工作在多核 CPU 上,所以自旋锁就是必须用到的.Nginx 中的自旋锁的定义,位于 ngx_spinlock.c 中,如下 ...
- 爬虫解析:XPath总结
1.加载 XML 文档 所有现代浏览器都支持使用 XMLHttpRequest 来加载 XML 文档的方法. 针对大多数现代浏览器的代码: var xmlhttp=new XMLHttpRequest ...