【装饰者模式】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) { // 我 ...
随机推荐
- 大数据,物联网(Internet of Things),万物互联网(Internet of Everything),云计算,雾计算,边缘计算(Edge Computing) 的区别和联系
大数据是一种规模大到在获取.存储.管理.分析方面大大超出了传统数据库软件工具能力范围的数据集合,具有海量的数据规模.快速的数据流转.多样的数据类型,高价值性和准确性五大特征,即5V(Volume, V ...
- Spring实战之通过XML装配bean
尽管Spring长期以来确实与XML有着关联,但现在需要明确的是,XML不再是配置Spring的唯一可选方案.Spring现在有了强大的自动化配置和基于Java的配置,XML不应该再是你的第一选择了. ...
- sql server 2005 修改动态端口,连接字符串为:需要改成:IP地址+逗号+端口号才行
1.sql server 2005 安装完毕后,默认是动态段,需要用sql brower 查询端口号:修改给固定端口后,格式为:IP地址+逗号+端口号. 2.sql 2000 的格式为:格式为:IP地 ...
- **Python中的深拷贝和浅拷贝详解
Python中的深拷贝和浅拷贝详解 这篇文章主要介绍了Python中的深拷贝和浅拷贝详解,本文讲解了变量-对象-引用.可变对象-不可变对象.拷贝等内容. 要说清楚Python中的深浅拷贝,需要 ...
- AOP的MethodBeforeAdvice
使用Spring自动生成代理类,spring利用的是动态代理机制 接口 Java代码 public interface UserDao { void addUser(); void deleteUse ...
- MySQL数据库篇之数据类型
主要内容: 一.数值类型 二.日期类型 三.字符串类型 四.枚举类型与集合类型 1️⃣ 数值类型 1.整数类型:tinyint smallint mediumint int bigint 作用 ...
- linux下connect超时时间探究
最近在linux做服务器开发的时候,发现了一个现象:服务器在启动的时候调用了 connect 函数,因为连接了一个不可用的端口,导致connect最后报出了 “Connection timed out ...
- Spark scala和java的api使用
1.利用scala语言开发spark的worcount程序(本地运行) package com.zy.spark import org.apache.spark.rdd.RDD import org. ...
- Spark 性能相关参数配置详解-Storage篇
随着Spark的逐渐成熟完善, 越来越多的可配置参数被添加到Spark中来, 本文试图通过阐述这其中部分参数的工作原理和配置思路, 和大家一起探讨一下如何根据实际场合对Spark进行配置优化. 由于篇 ...
- int类型与char类型的转换
---------siwuxie095 Java对char类型的数据在底层是按int类型来处理的 (只是显示出来仍然是字符型) 1.int类型与char ...