设计模式之“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.这 ...
随机推荐
- 10个html5增加的重要新特性和内容
文章开篇之前我们先了解一下什么是html5,百度上是这样定义html5的:万维网的核心语言.标准通用标记语言下的一个应用超文本标记语言(HTML)的第五次重大修改. 其实说白了html5也就是人为定义 ...
- 【Asp.net Core】在 Linux 子系统中安装 nginx 并配置反向代理
上一篇鸟文中,老周已经介绍过在 Ubuntu 子系统中安装 dotnet-sdk 的方法,本文老周给大伙伴们说说安装 nginx 服务,并配置反向代理.同样,老周假设你从来没有用过 Linux,所以老 ...
- Python 使用Pillow模块生成验证码
1.安装 pip3 install pillow 2.使用步骤 生成验证码和验证字符串 绘制图片,将验证码放入session中 将图片返回给页面 3.代码demo #!/usr/bin/env pyt ...
- set类型
set 集合 是string类型的无序集合.我们可以对集合去交集 并集 差集 sadd 添加元素 不允许有重复的值 smembers 查看元素中的值 srem 删除set中的值
- PID算法
所谓PID就是比例-积分-微分的英文缩写,但并不是必须同时具备这三种算法,也可以是 PD, PI,甚至只有 P算法控制,下面分别介绍每个参数的含义:首先需要明确一个事实就是,要实现PID算法,必须在硬 ...
- python_为被装饰的函数保留元数据
案例: 在函数对象中保存着一些函数的元数据,如: f.__name__ 函数名 f.__doc__ 函数文档 f.__moudle__ 函数所 ...
- Windows核心编程&内存管理
1. 每个进程都有自己的虚拟地址空间,对于32位机器而言,这个地址空间的大小为4GB(2^32 / 1024^3),这个虚拟地址空间只不过是一个内存地址空间, 为了能够正常读/写数据,我们还需要把物理 ...
- Servlet--HttpSessionBindingListener接口,HttpSessionBindingEvent类
HttpSessionBindingListener 接口 定义 public interface HttpSessionBindingListener 这个对象被加入到 HTTP 的 session ...
- Java的IO系统
Java IO系统 "对语言设计人员来说,创建好的输入/输出系统是一项特别困难的任务." 由于存在大量不同的设计方案,所以该任务的困难性是很容易证明的.其中最大的 ...
- 如何书写优雅、漂亮的SQL脚本?
本篇来聊聊如何书写漂亮.整洁.优雅的SQL脚本,下面这些是我个人总结.整理出来的.姑且做个抛砖引玉吧,呵呵,欢迎大家一起来讨论. 我们首先来看看一段创建数据表的脚本(如下所示),你是否觉得有什么不 ...