第8章 装饰模式(Decorator Pattern)
原文 第8章 装饰模式(Decorator Pattern)
概述:
装饰模式是在不必改变原类文件和使用继承的情况下,动态地扩展一个对象的功能。它是通过创建一个包装对象,也就是装饰来包裹真实的对象。
装饰模式的特点:
结构图:

举例:假设我们要开发一个照相管用的程序
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
//照相 public abstract class Picture { public abstract void Draw(); } //绘制一个照片 public class People : Picture { public override void Draw() { Console.WriteLine("照一张相片"); } } |
假设我们不仅只照相,而且为了满足客户的需要有的时候需要给相片增加一个相框
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
public interface PhotoFrame { void SetFrame(); } public class PeopleWithFram :People, PhotoFrame { public override void Draw() { base.Draw(); //照完加相框 SetFrame(); } public void SetFrame() { //给相片加相框方法 } } |
好 需求又来了,毕竟有钱人还是很多了嘛,不仅要相框,还需要打蜡上保护膜
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
public interface ProtectPic { void ProtectImage(); } public class PeopleWithFramWithProtect : People, PhotoFrame, ProtectPic { public override void Draw() { base.Draw(); //先上保护膜打上蜡 ProtectImage(); //在上相框 SetFrame(); } public void SetFrame() { //给相片加相框方法 } public void ProtectImage() { //给相片打蜡上保护膜 } } |
/好,这个时候需求又来了,毕竟不是人人都那么完美,毕竟有丑姑娘嘛,需要PS处理一下,那我们是不是又得定义一个PS接口,然后写个子类去继承呢?“子类复子类,子类何其多”。这种接口继承的方式虽然是解决问题,同时也带来了一系列新的问题,子类可能需要多重继承,这个在某些情况下违反了类的单一职责。后续如来来新的需求子类会变的非常庞大。
我们看看装饰是怎么解决这个问题的
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
|
public class Decorate : Picture { public Picture picture; public Decorate(Picture pic) { this.picture=pic; } public override void Draw() { Console.WriteLine("照一张相片"); } } //相框 public class WithFram : Decorate { public WithFram(Picture pic):base(pic) { } public override void Draw() { SetFrame(); base.Draw(); } public void SetFrame() { //给相片加相框方法 } } //打蜡上保护膜 public class WithProtect : Decorate { public WithProtect(Picture pic) : base(pic) { } public override void Draw() { ProtectImage(); base.Draw(); } public void ProtectImage() { //给相片打蜡上保护膜 } } class Program { static void Main(string[] args) { //照相 Picture pic = new People(); pic.Draw(); //照完像上蜡上保护膜 Picture picProtect = new People(); Decorate dec = new WithProtect(pic); dec.Draw(); //照完上蜡上保护膜上相框 Picture picProtectFrame = new People(); Decorate decProtect = new WithProtect(picProtectFrame); Decorate frame = new WithFram(decProtect);//Decorator模式的精妙所在 frame.Draw(); } } |
用装饰模式,大大减少了子类的继承,并且在调用的时候,可以对上级对象进行再次封装,这个也是Decorator模式非常经典的一个地方!
适用性:
优点:
缺点:
设计原则:
2. 类应设计的对扩展开放,对修改关闭
第8章 装饰模式(Decorator Pattern)的更多相关文章
- 二十四种设计模式:装饰模式(Decorator Pattern)
装饰模式(Decorator Pattern) 介绍动态地给一个对象添加一些额外的职责.就扩展功能而言,它比生成子类方式更为灵活.示例有一个Message实体类,某个对象对它的操作有Insert()和 ...
- 乐在其中设计模式(C#) - 装饰模式(Decorator Pattern)
原文:乐在其中设计模式(C#) - 装饰模式(Decorator Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 装饰模式(Decorator Pattern) 作者:weba ...
- 设计模式-装饰模式(Decorator Pattern)
装饰模式(Decorator Pattern):动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活
- 设计模式-09装饰模式(Decorator Pattern)
1.模式动机 一般有两种方式可以实现给一个类或对象增加行为: 继承机制:使用继承机制是给现有类添加功能的一种有效途径,通过继承一个现有类可以使得子类在拥有自身方法的同时还拥有父类的方法.但是这种方法是 ...
- 设计模式系列之装饰模式(Decorator Pattern)——扩展系统功能
说明:设计模式系列文章是读刘伟所著<设计模式的艺术之道(软件开发人员内功修炼之道)>一书的阅读笔记.个人感觉这本书讲的不错,有兴趣推荐读一读.详细内容也可以看看此书作者的博客https:/ ...
- 装饰模式(Decorator pattern)
装饰模式(Decorator pattern): 又名包装模式(Wrapper pattern), 它以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案. 装饰模式以对客户透明的方式动态的给 ...
- 设计模式系列之装饰模式(Decorator Pattern)
装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其结构.这种类型的设计模式属于结构型模式,它是作为现有的类的一个包装.这种模式创建了一个装饰类,用来包装原 ...
- 使用C# (.NET Core) 实现装饰模式 (Decorator Pattern) 并介绍 .NET/Core的Stream
该文章综合了几本书的内容. 某咖啡店项目的解决方案 某咖啡店供应咖啡, 客户买咖啡的时候可以添加若干调味料, 最后要求算出总价钱. Beverage是所有咖啡饮料的抽象类, 里面的cost方法是抽象的 ...
- 装饰模式Decorator Pattern
1.主要优点 装饰模式的主要优点如下: (1) 对于扩展一个对象的功能,装饰模式比继承更加灵活性,不会导致类的个数急剧增加. (3) 可以对一个对象进行多次装饰,通过使用不同的具体装饰类以及这些装饰类 ...
- 设计模式——装饰模式(Decorator Pattern)
装饰模式:动态的给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活. UML图: 模型类: Component类: package com.cnblog.clarck; /** ...
随机推荐
- Nginx+Varnish
Nginx+Varnish 实现动静分离,为服务器分流,降低服务器负载 相必大家在看加快网站响应速度方面的文章时,都提过这么一条:动静分离.那怎样实现动静分离呢,这里笔者就亲自搭建相关服务实现动静分离 ...
- 下的生产环境was重新启动不同意,怎么做?
前一段时间上线.遇到一个jndi问题,它是如何是个问题?它是在测试环境中的原始没有问题,在生产环境中,您无法连接生产数据库,然后发现问题,那是,ibm工具生成在测试环境中自己主动的连接jndi资源文件 ...
- UIScrollViewA都PI得知。
//1.设定滚定条的样式 typedef NS_ENUM(NSInteger, UIScrollViewIndicatorStyle) { UIScrollViewIndicatorStyleDefa ...
- UVA434 - Matty's Blocks
option=com_onlinejudge&Itemid=8&page=show_problem&category=457&problem=375&mosms ...
- 自定义DB连接池实现
实现一个简单的数据库连接池 1,连接池接口 package dbsource; import java.sql.Connection; import java.sql.SQLException; /* ...
- 举例说, Decorator模式(Decorator Pattern)
前言 在食品工业中的装饰图案具有比较广泛的应用,大多数的两个图案和在网上的例子饮食相关的,一旦被称为电影的手表,点咖啡要加糖要加奶昔要加这加那的时候.感觉好有派~好高大上啊~.为啥我在小卖部都是 ...
- lua基金会【五岁以下儿童】I/O文件操作
--[[ lua操作相关文件I/O ]]-- --件,假设该文件不存在的话, --lua会帮助我们在你规定的文件夹下创建这个文件,前提是该文件夹要存在 --[[ 同一时候我们应该掌握写入文件的模式: ...
- Android setDisplayOptions 具体的使用说明
Android有几个地方使用位计算.实例Intent Flags,它们的定义View onMeasure(int widthMeasureSpec, int heightMeasureSpec),并且 ...
- 嵌入在网页上Flash媒体播放器(1)
做的项目,在不久的将来相关的Flash玩家使用,需要播放视频的网页上,不同的视频资源,需要不同的球员.基于使用稳定性.的嵌入式和嵌入式复杂性能的优点概括起来有两种方式(不同的玩家),视频资源也略有不同 ...
- 微通道产品经理Grover采访:美国的微通道设计
"'哥'在中国是一种尊称吗?哈哈.我们平时都叫张小龙'龙哥'." "是的.Dan哥,当你认为某个人牛逼的时候,你就能够叫他'哥'." 我对于Dan Grover ...