设计模式之“Decorator”注疏#02

装饰模式在某种意义上来说也是挺原始的,
它首先需要一个你被装饰的基础类,
再来是需要一个基于这个基础类的原始包装器,可以看作是其它包装器的基础类
进而通过继承这个包装器,来构建出多个具有各自功能的特定包装器
最后,是通过层层组合这些包装器(通过一层层地使用构造函数的方式),来构建出你最终需要的包含多个功能的产品类
一开始接触这一过程时,不免会感觉繁杂、手足无措。不就是一个不断装饰、不断包裹的过程么,为何需要这么多的步骤呢?
那么,我可以首先给出一个直观解释,并且通过这个直观解释,可以在一定程度上去解释这里所谓的装饰模式的“原始”表示什么意思。
我们可以把一般的抽象的“装饰过程”想象为:不断地往被装饰物上面添加装饰物件的过程。(特别地,我们在这里考察一个特殊的装饰过程:往墙壁上不断添加各色墙纸的过程,来作为例子。)
(一)
那么,从一般性的装饰过程来看,首先要解决的问题便是:到底为什么物件做装饰呢?你是为一盏台灯做装饰,还是为一张桌子做装饰,又或是为了一面墙做装饰?所以,我们需要一个基础类来决定,被装饰物到底是什么。(在这里,我们的被装饰物是一面墙,所以,我们需要声明“墙”这个类作为我们的基础类。)
(二)
有了装饰的目标之后,下一个要解决的问题是拿什么来做装饰呢?你是用一朵花来做装饰呢?还是用一个气球?又或是用一张海报来做装饰?并且,你选中的这个装饰物还和你的被装饰物牢牢相关。例如,装饰汽车的花朵和装饰卧室的花朵品种可能并不相同;装饰户外的气球和装饰办公室的气球风格,也可能不同。
所以,你不仅要决定做装饰器物(也即是装饰器decorator)的品种,还得要让这个装饰器牢牢地和你的被装饰物相关。(在这里,我们需要装饰墙壁的墙纸。所以你需要建立一个“墙纸”类,并且它是同你的被装饰物“墙”相关)
需要注意的是,这一步的装饰物是一个泛指。例如装饰汽车的花朵、装饰办公室的气球、装饰墙壁的墙纸。可是,这个花朵是什么颜色的、气球是什么形状的、墙纸是什么花纹的,我们并不知道。所以在这一步,声明的仅仅是一个具备功能性泛指的装饰器基础类。
(三)
自然地,下一步的工作便是细化你的装饰器。在这个一般性的装饰器下,例如墙纸,你的这个墙纸到底是什么花纹、什么颜色、有什么特殊功效。这就可以通过构建一个个具体的子类来实现。
(四)
最后,有了被装饰的物件、有了各种装饰器,那么,就可以通过原始的被装饰物,以及各个装饰器的层层嵌套构造函数,来构建出一个具备各种特定功能的产品。
所以,整体考察下来,这个过程还是挺直观的。但是,说其“原始”,是因为你的很多特殊装饰器的构造都必须要通过层层嵌套才能够创造。例如,我装饰汽车的花朵为什么不可以直接拿去装饰卧室?从现实直观上,我们是可以这样做的,但是它却不能在“类”的构建体系中实现一个方便的迁移,不得不从最开始被装饰物出发,一层层地添加装饰物来实现最后的你需要的产品。
// 1. Basic class, the decorated thing
public class Wall {
private String _name;
public Wall();
public void set(String name) { _name = name; }
public String get() { return _name; }
} // 2. General decorator class
public class WallPaper extends Wall {
protected Wall _wall;
public WallPaper(Wall wall) { _wall = wall; } public void set(String name) { _wall.set(name); }
public String get() { return _wall.get(); }
} // 3.1 Specific decorator: red wall paper
public class RedWallPaper extends WallPaper {
public RedWallPaper(Wall wall) { super(wall); } // ... other specific features
} // 3.2 Specific decorator: blue wall paper
public class BlueWallPaper extends WallPaper {
public BlueWallPaper(Wall wall) { super(wall); } // ... other specific features
} // 4. Final decoration: colorful wall
public class Decoration {
public static void main(String[] args) {
BlueWallPaper ColorfulWall =
new BlueWallPaper( new RedWallPaper(new Wall()) );
}
}
再来看更为一般和抽象的来自Thinking in Java的装饰模式的代码示例:
// 1. Basic class, the decorated thing
class Basic {
private String value;
public void set(String val) { value = val; }
public String get() { return value; }
} // 2. General decorator class
class Decorator extends Basic {
protected Basic basic;
public Decorator(Basic basic) { this.basic = basic; }
public void set(String val) { basic.set(val); }
public String get() { return basic.get(); }
} // 3.1 Specific decorator
class TimeStamped extends Decorator {
private final long timeStamp;
public TimeStamped(Basic basic) {
super(basic);
timeStamped = new Date().getTime();
}
public long getStamp() { return timeStamp; }
} // 3.2 Specific decorator
class SerialNumbered extends Decorator {
private static long counter = 1;
private final long serialNumber = counter++;
public SerialNumbered(Basic basic) { super(basic); }
public getSerialNumber() { return serialNumber; }
} // 4. Decoration
public class Decoration {
public static void main(String[] args) {
TimeStamped t = new TimeStamped( new Basic() );
TimeStamped t2 = new TimeStamped(
new SerialNumbered(new Basic()) );
//! t2.getSerialNumber(); // Not available SerialNumbered s = new SerialNumbered( new Basic() );
SerialNumbered s2 = new SerialNumbered(
new TimeStamped(new Basic()) );
//! s2.getStamp(); // Not available
}
}
这样,装饰模式应该就可以理解了。
设计模式之“Decorator”注疏#02的更多相关文章
- 设计模式 装饰模式(Decorator)
设计模式 装饰模式(Decorator) @author ixenos 装饰模式是什么 1.装饰模式以对客户端透明的方式对象的功能,是继承关系的一个替代方案,但装饰模式可以在不创造更多子类的情况下,对 ...
- 【设计模式】结构型02装饰模式(Decorator Pattern)
装饰模式(Decorator Pattern) 意图:动态地给一个对象添加一些额外的职责.就增加功能来说,装饰器模式相比生成子类更为灵活. 主要解决:一般的,我们为了扩展一个类经常使用继承方式实现,由 ...
- [学习笔记]设计模式之Decorator
写在前面 为方便读者,本文已添加至索引: 设计模式 学习笔记索引 Decorator(装饰)模式,可以动态地给一个对象添加一些额外的职能.为了更好地理解这个模式,我们将时间线拉回Bridge模式笔记的 ...
- 设计模式--装饰者设计模式(Decorator)
装饰者模式又叫包装模式. 通过另一个对象来扩展自己的行为,在不破坏类的封装的情况下,实现松耦合,易扩展的效果. 抽象组件角色: 一个抽象接口,是被装饰类和装饰类的父接口可以给这些对象动态地添加职责 ...
- 设计模式之——Decorator模式
Decorator模式又叫装饰者模式,这种模式是为了满足Java开发的"面向扩展开放,面向修改闭源"的开发原则设计出来的. 在装饰者模式中,不修改源类的代码,却能修改源类中方法的功 ...
- Java--23种设计模式之decorator模式
装饰模式:装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案,提供比继承更多的灵活性.动态给一个对象增加功能,这些功能可以再动态的撤消.增加由一些基本功能的排列组合而产生的非常大量的 ...
- [工作中的设计模式]装饰模式decorator
一.模式解析 装饰模式又名包装(Wrapper)模式.装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案. 装饰模式的要点主要是: 1.需要对已有对象扩展新的功能,又不希望改变原有对 ...
- 设计模式之“Observer”注疏#01
原文首发于我的微信公众号:GeekArtT. Observer设计模式是为了解决"信息同步更新"的问题而存在的.它试图解决这样一个问题:如果有"一堆对象"都跟随 ...
- 设计模式之Decorator(油漆工)(转)
Decorator常被翻译成"装饰",我觉得翻译成"油漆工"更形象点,油漆工(decorator)是用来刷油漆的,那么被刷油漆的对象我们称decoratee.这 ...
随机推荐
- UnityShader 表面着色器简单例程集合
0.前言 这些简单的shader程序都是写于2015年的暑假.当时实验室空调坏了,30多个人在实验室中挥汗如雨,闷热中学习shader的日子还历历在目.这些文章闲置在我个人博客中,一年将过,师弟也到了 ...
- Deep Learning速成教程
引言 深度学习,即Deep Learning,是一种学习算法(Learning algorithm),亦是人工智能领域的一个重要分支.从快速发展到实际应用,短短几年时间里, ...
- mysql按照天统计报表,当天没有数据,填0
1.问题复现: 按照天数统计每天的总数,如果其中有几天没有数据,那么group by 返回会忽略那几天,如何填充0?如下图,统计的10-3~10-10 7天的数据,其中只有8号和10号有数据,这样返回 ...
- YourPHP笔记
http://blog.sina.com.cn/s/blog_7c54793101016qq1.htm 基础认识: Ø yourphp安装为子目录时不可以以"yourphp"为文 ...
- 织梦中data文件夹是存放什么内容的
dede(织梦)的data文件夹下的文件及文件夹也不少,我们来一个一个的介绍下. 1. admin文件夹 admin文件夹 管理员用到的文件夹,一般是后台的配置文件. 第一个文件,idc.txt 配置 ...
- 【视频编解码·学习笔记】3. H.264视频编解码工程JM的下载与编解码
一.下载JM工程: JM是H.264标准制定团队所认可的官方参考软件.网址如下 http://iphome.hhi.de/suehring/tml/ 从页面中可找到相应的工程源码,本次选择JM 8.6 ...
- [转]maven打包报错:Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.5:test
源文URL:http://blog.csdn.net/caiwenfeng_for_23/article/details/44514947 mvn compile 没有问题,mvn package的 ...
- 高质量JAVA代码编写规范
1. Java 命名约定 除了以下几个特例之外,命名时应始终采用完整的英文描述符.此外,一般应采用小写字母,但类名.接口名以及任何非初始单词的第一个字母要大写. 1.1 一般概念 * 尽量使用完整的英 ...
- 5分钟学会使用gitlab
第一次接触到gitlab,操作不是很熟练,犯了一堆错,在多次尝试之后,大概了解了流程,这篇文章主要帮助大家快速上手gitlab,如果文章有什么不对的地方,欢迎在评论区留言~ 1.新建项目 首先你得有个 ...
- junit4X系列--Assert与Hamcrest
原文出处:http://www.blogjava.net/DLevin/archive/2012/05/12/377960.html.感谢作者无私分享 到目前,JUnit4所有的核心源码都已经讲解过了 ...