装饰模式在某种意义上来说也是挺原始的,

  1. 它首先需要一个你被装饰的基础类,

  2. 再来是需要一个基于这个基础类的原始包装器,可以看作是其它包装器的基础类

  3. 进而通过继承这个包装器,来构建出多个具有各自功能的特定包装器

  4. 最后,是通过层层组合这些包装器(通过一层层地使用构造函数的方式),来构建出你最终需要的包含多个功能的产品类

一开始接触这一过程时,不免会感觉繁杂、手足无措。不就是一个不断装饰、不断包裹的过程么,为何需要这么多的步骤呢?

那么,我可以首先给出一个直观解释,并且通过这个直观解释,可以在一定程度上去解释这里所谓的装饰模式的“原始”表示什么意思。

我们可以把一般的抽象的“装饰过程”想象为:不断地往被装饰物上面添加装饰物件的过程。(特别地,我们在这里考察一个特殊的装饰过程:往墙壁上不断添加各色墙纸的过程,来作为例子。)

(一)

那么,从一般性的装饰过程来看,首先要解决的问题便是:到底为什么物件做装饰呢?你是为一盏台灯做装饰,还是为一张桌子做装饰,又或是为了一面墙做装饰?所以,我们需要一个基础类来决定,被装饰物到底是什么。(在这里,我们的被装饰物是一面墙,所以,我们需要声明“墙”这个类作为我们的基础类。)

(二)

有了装饰的目标之后,下一个要解决的问题是拿什么来做装饰呢?你是用一朵花来做装饰呢?还是用一个气球?又或是用一张海报来做装饰?并且,你选中的这个装饰物还和你的被装饰物牢牢相关。例如,装饰汽车的花朵和装饰卧室的花朵品种可能并不相同;装饰户外的气球和装饰办公室的气球风格,也可能不同。

所以,你不仅要决定做装饰器物(也即是装饰器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的更多相关文章

  1. 设计模式 装饰模式(Decorator)

    设计模式 装饰模式(Decorator) @author ixenos 装饰模式是什么 1.装饰模式以对客户端透明的方式对象的功能,是继承关系的一个替代方案,但装饰模式可以在不创造更多子类的情况下,对 ...

  2. 【设计模式】结构型02装饰模式(Decorator Pattern)

    装饰模式(Decorator Pattern) 意图:动态地给一个对象添加一些额外的职责.就增加功能来说,装饰器模式相比生成子类更为灵活. 主要解决:一般的,我们为了扩展一个类经常使用继承方式实现,由 ...

  3. [学习笔记]设计模式之Decorator

    写在前面 为方便读者,本文已添加至索引: 设计模式 学习笔记索引 Decorator(装饰)模式,可以动态地给一个对象添加一些额外的职能.为了更好地理解这个模式,我们将时间线拉回Bridge模式笔记的 ...

  4. 设计模式--装饰者设计模式(Decorator)

    装饰者模式又叫包装模式. 通过另一个对象来扩展自己的行为,在不破坏类的封装的情况下,实现松耦合,易扩展的效果.   抽象组件角色: 一个抽象接口,是被装饰类和装饰类的父接口可以给这些对象动态地添加职责 ...

  5. 设计模式之——Decorator模式

    Decorator模式又叫装饰者模式,这种模式是为了满足Java开发的"面向扩展开放,面向修改闭源"的开发原则设计出来的. 在装饰者模式中,不修改源类的代码,却能修改源类中方法的功 ...

  6. Java--23种设计模式之decorator模式

    装饰模式:装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案,提供比继承更多的灵活性.动态给一个对象增加功能,这些功能可以再动态的撤消.增加由一些基本功能的排列组合而产生的非常大量的 ...

  7. [工作中的设计模式]装饰模式decorator

    一.模式解析 装饰模式又名包装(Wrapper)模式.装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案. 装饰模式的要点主要是: 1.需要对已有对象扩展新的功能,又不希望改变原有对 ...

  8. 设计模式之“Observer”注疏#01

    原文首发于我的微信公众号:GeekArtT. Observer设计模式是为了解决"信息同步更新"的问题而存在的.它试图解决这样一个问题:如果有"一堆对象"都跟随 ...

  9. 设计模式之Decorator(油漆工)(转)

    Decorator常被翻译成"装饰",我觉得翻译成"油漆工"更形象点,油漆工(decorator)是用来刷油漆的,那么被刷油漆的对象我们称decoratee.这 ...

随机推荐

  1. [数据库] SQL查询语句表行列转换及一行数据转换成两列

    原文来自:http://blog.csdn.net/Eastmount/article/details/50559008 本文主要讲述了SQL查询语句表之间的行列转换,同时也包括如何将一行数据转换成两 ...

  2. cesium编程入门(三)开始使用cesium开发

    搭建最简的开发环境 这一节来搭建一个最简单的能运行的helloworld,以后的代码也会在这一节的基础上慢慢增加 创建文件夹 mkdir cesium-test cd cesium-test 引入编译 ...

  3. DFS算法(——模板习题与总结)

    首先,需要说明的是搜索算法本质上也是枚举的一种,时间复杂度还是很高的,遇到问题(特别是有水平的比赛上),不要优先使用搜索算法. 这里总结一下DFS算法: 1.从图中某个顶点出发,访问v. 2.找出刚访 ...

  4. solrcloud(solr集群版)安装与配置

    1 Solr集群 1.1 什么是SolrCloud SolrCloud(solr 云)是Solr提供的分布式搜索方案,当你需要大规模,容错,分布式索引和检索能力时使用 SolrCloud.当一个系统的 ...

  5. JAVA:成员变量和局部变量的区别

    1.作用于不同: 局部变量的作用域仅限于定义它的方法 成员变量的作用域在整个类的内部都是可见的 2.初始值不同 JAVA会给成员变量一个初始值 JAVA不会给局部变量赋予初始值 3.在同一个方法中,不 ...

  6. vue-router自动判断左右翻页转场动画

    前段时间做了一个移动端spa项目,技术基于 :vue + vue-router + vuex + mint-ui 因为使用了vue-cli脚手架的webpack模版,所有页面都以.vue为后缀的文件作 ...

  7. 月薪20k以上的高级程序员需要学习哪些技术呢?

    课程内容: 源码分析.分布式架构.微服务架构.性能优化.团队协作效率.双十一项目实战 适用对象: 1-5年或更长软件开发经验,没有工作经验但基础非常扎实,对java工作机制,常用设计思想,常用java ...

  8. 直接请求转发(Forward)和间接请求转发(Redirect)两种区别?

    用户向服务器发送了一次HTTP请求,该请求肯能会经过多个信息资源处理以后才返回给用户,各个信息资源使用请求转发机制相互转发请求,但是用户是感觉不到请求转发的.根据转发方式的不同,可以区分为直接请求转发 ...

  9. CCF系列之模板生成系统( 201509-3 )

    试题名称: 模板生成系统 试题编号: 201509-3 时间限制: 1.0s 内存限制: 256.0MB 问题描述 成成最近在搭建一个网站,其中一些页面的部分内容来自数据库中不同的数据记录,但是页面的 ...

  10. python基础8之自定义模块、if __name__==__main__:解释

    一.自定义模块与使用 python模块说明:类似于函数式编程和面向过程编程,函数式编程则完成一个功能,其他代码用来调用即可,提供了代码的重用性和代码间的耦合.而对于一个复杂的功能来,可能需要多个函数才 ...