装饰(Decorator)模式
一、 装饰(Decorator)模式
装饰(Decorator)模式又名包装(Wrapper)模式[GOF95]。装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案。
二、 装饰模式的结构
- 抽象构件(Component)角色:给出一个抽象接口,以规范准备接收附加责任的对象。
- 具体构件(Concrete Component)角色:定义一个将要接收附加责任的类。
- 装饰(Decorator)角色:持有一个构件(Component)对象的实例,并定义一个与抽象构件接口一致的接口。
- 具体装饰(Concrete Decorator)角色:负责给构件对象"贴上"附加的责任
/// <summary>
/// 装饰(Decorator)模式
/// 装饰(Decorator)模式又名包装(Wrapper)模式[GOF95]。
/// 装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案。
/// </summary>
class Program
{
static void Main(string[] args)
{
// 创建的书和视频和显示
Book book = new Book("巴金", "家", );
Video video = new Video("不详","扫毒", , );
book.Display();
video.Display(); // 查看图书,然后借阅
Console.WriteLine("\n查看图书,然后借阅:"); Borrowable borrowvideo = new Borrowable(book);
borrowvideo.BorrowItem("小三");
borrowvideo.BorrowItem("小四"); borrowvideo.Display();
Console.ReadLine();
}
} /// <summary>
/// 抽象构件(Component)角色
/// </summary>
public abstract class LibraryItem
{
// 字段
private int numCopies;
// 属性
public int NumCopies
{
get { return numCopies; }
set { numCopies = value; }
}
// 方法
public abstract void Display();
} /// <summary>
/// 具体构件(Concrete Component)角色
/// </summary>
public class Book : LibraryItem
{
// 字段
private string author;
private string title; // 构造函数
public Book(string author, string title, int numCopies)
{
this.author = author;
this.title = title;
this.NumCopies = numCopies;
} // 函数
public override void Display()
{
Console.WriteLine(" 书(Book) ------ ");
Console.WriteLine(" 作者: {0}", author);
Console.WriteLine(" 书名: {0}", title);
Console.WriteLine(" # 副本: {0}", NumCopies);
}
} /// <summary>
/// 具体构件(Concrete Component)角色
/// </summary>
public class Video : LibraryItem
{
// 字段
private string director;
private string title;
private int playTime; // 构造函数
public Video(string director, string title,int numCopies, int playTime)
{
this.director = director;
this.title = title;
this.NumCopies = numCopies;
this.playTime = playTime;
} // 方法
public override void Display()
{
Console.WriteLine(" 视频(Video) ----- ");
Console.WriteLine(" 导演: {0}", director);
Console.WriteLine(" 片名: {0}", title);
Console.WriteLine(" # 副本: {0}", NumCopies);
Console.WriteLine(" 时长: {0} 分钟", playTime);
} } /// <summary>
/// 装饰(Decorator)角色
/// </summary>
public abstract class Decorator : LibraryItem
{
// 字段
protected LibraryItem libraryItem; // 构造函数
public Decorator(LibraryItem libraryItem)
{ this.libraryItem = libraryItem; } // 方法
public override void Display()
{ libraryItem.Display(); } } /// <summary>
/// 具体装饰(Concrete Decorator)角色
/// </summary>
public class Borrowable : Decorator
{
// 字段
protected ArrayList borrowers = new ArrayList(); // 构造函数
public Borrowable(LibraryItem libraryItem)
: base(libraryItem) { } // 方法
public void BorrowItem(string name)
{
borrowers.Add(name);
libraryItem.NumCopies--;
} public void ReturnItem(string name)
{
borrowers.Remove(name);
libraryItem.NumCopies++;
} public override void Display()
{
base.Display();
foreach (string borrower in borrowers)
Console.WriteLine(" 借阅人: {0}", borrower);
}
}
三、 装饰模式应当在什么情况下使用
在以下情况下应当使用装饰模式:
- 需要扩展一个类的功能,或给一个类增加附加责任。
- 需要动态地给一个对象增加功能,这些功能可以再动态地撤销。
- 需要增加由一些基本功能的排列组合而产生的非常大量的功能,从而使继承关系变得不现实。
4. 如果只有一个 具体构件(Concrete Component)角色 的时候 可以不要抽象构件(Component)角色
//创建ConcreteComponent和两个修饰符
ConcreteComponent c = new ConcreteComponent();
ConcreteDecoratorA d1 = new ConcreteDecoratorA();
ConcreteDecoratorB d2 = new ConcreteDecoratorB(); // 链接修饰符
d1.SetComponent(c);
d2.SetComponent(d1); d2.Operation(); /// <summary>
/// 抽象构件(Component)角色
/// </summary>
public abstract class Component
{
// 方法
public abstract void Operation();
}
// "具体构建"
public class ConcreteComponent : Component
{
// 方法
public override void Operation()
{
Console.WriteLine("具体对象的操作");
}
}
// 装饰(Decorator)角色
public abstract class Decorators : Component
{
// 字段
protected Component component;
// 方法
public void SetComponent(Component component)
{
this.component = component;
}
public override void Operation()
{
if (component != null)
component.Operation();
}
} // "具体装饰A"
class ConcreteDecoratorA : Decorators
{
private string addedState;
public override void Operation()
{
base.Operation();
addedState = "new state";
Console.WriteLine("具体装饰对象A的操作");
}
} // "具体装饰B"
public class ConcreteDecoratorB : Decorators
{
public override void Operation()
{
base.Operation();
AddedBehavior();
Console.WriteLine("具体装饰对象B的操作");
}
void AddedBehavior()
{
}
}
Console.WriteLine("\n=========搭配衣服=============\n");
Person xc = new Person("鸟人-安德森");
TShirts tx = new TShirts();
BigTrouser kk = new BigTrouser();
tx.Decorate(xc);
kk.Decorate(tx);
kk.Show();
/// <summary>
/// 如果只有一个 具体构件(Concrete Component)角色 的时候
/// 可以不要抽象构件(Component)角色
/// </summary>
public class Person
{
public Person()
{ }
private string name;
public Person(string name)
{
this.name = name;
}
public virtual void Show()
{
Console.WriteLine("装扮的{0}", name);
}
}
///装饰(Decorator)角色
public class Finery : Person
{
protected Person component;
//打扮
public void Decorate(Person component)
{
this.component = component;
}
public override void Show()
{
if (component != null)
component.Show();
}
}
/// <summary>
/// 具体装饰
/// </summary>
public class TShirts : Finery
{
public override void Show()
{
Console.WriteLine("大T恤");
base.Show();
}
}
/// <summary>
/// 具体装饰
/// </summary>
public class BigTrouser : Finery
{
public override void Show()
{
Console.WriteLine("大垮裤");
base.Show();
}
}
装饰(Decorator)模式的更多相关文章
- 装饰(Decorator)模式
1.装饰(Decorator)模式 动态给一个对象添加一些额外的职责.就增加功能来说,装饰模式比生成子类更为灵活.Component是定义一个对象接口.可以给这些对象动态地添加职责.Concre ...
- 《Head First 设计模式》ch.3 装饰(Decorator)模式
设计原则 类应该对修改关闭,对扩展开放(开放-关闭原则).在每个地方使用开放-关闭原则是一种浪费,也没有必要,因为这通常会引入新的抽象层次,增加代码复杂度.需要把注意力集中在设计中最有可能改变的地方. ...
- Java 实现装饰(Decorator)模式
在Java在.io反映非常多类包下是典型的装饰格局,例如: new BufferedOutputStream(OutputStream out) new BufferedInputStream(Inp ...
- 设计模式C++描述----10.装饰(Decorator)模式
一. 举例 我之前做过一个文件系统就叫 MyFileSys 吧,后来的话,客户想加入一些附加功能,比如压缩.加密.杀毒之类的操作,这些附加操作没有先后顺序,比如你可以先压缩再加密,也可以先杀毒再压缩, ...
- 九、结构模式之装饰(Decorator)模式
装饰模式又叫包装模式,装饰模式以客户端透明的方式扩展对象的功能,是继承关系的一个替代方案.装饰模式可以在不使用创造更多的子类的情况下,将对象的功能加以扩展. 装饰模式结构图如下: 其包含的角色就分为: ...
- Java与模式:装饰(Decorator)模式
装饰模式使用被装饰类的一个子类的实例.把client的调用委派到被装饰类,装饰模式的关键在于这样的扩展是全然透明的. 装饰模式在Java种使用也非常广泛,比方我们在又一次定义button.对话框等 ...
- Java 装饰器模式详解
转载请注明出处:http://blog.csdn.net/zhaoyanjun6/article/details/56488020 前言 在上面的几篇文章中,着重介绍了Java 中常见的 IO 相关知 ...
- 设计模式(三):“花瓶+鲜花”中的装饰者模式(Decorator Pattern)
在前两篇博客中详细的介绍了"策略模式"和“观察者模式”,今天我们就通过花瓶与鲜花的例子来类比一下“装饰模式”(Decorator Pattern).在“装饰模式”中很好的提现了开放 ...
- 设计模式(九)装饰者模式(Decorator Pattern)
一.引言 在软件开发中,我们经常想要对一类对象添加不同的功能,例如要给手机添加贴膜,手机挂件,手机外壳等,如果此时利用继承来实现的话,就需要定义无数的类,如StickerPhone(贴膜是手机类).A ...
- 说说设计模式~装饰器模式(Decorator)~多功能消息组件的实现
返回目录 为何要设计多功能消息组件 之前写过一篇装饰器模式的文章,感觉不够深入,这次的例子是实现项目中遇到的,所以把它拿出来,再写写,之前也写过消息组件的文章,主要采用了策略模式实现的,即每个项目可以 ...
随机推荐
- Ubuntu 下使用 mutt 和 msmtp 发送 Gmail 邮件
参考: http://www.cnblogs.com/refrag/archive/2012/11/28/2793533.html http://www.habadog. ...
- expected_conditions 库的使用方法
from selenium.webdriver.support import expected_conditions as EC 例子一: 例子二:(判断元素存在文本"糯米")
- 【转】JMeter入门
一.JMeter概述 JMeter就是一个测试工具,相比于LoadRunner等测试工具,此工具免费,且比较好用,但是前提当然是安装Java环境: JMeter可以做 (1)压力测试及性能测试: (2 ...
- Vue.js:表单
ylbtech-Vue.js:表单 1.返回顶部 1. Vue.js 表单 这节我们为大家介绍 Vue.js 表单上的应用. 你可以用 v-model 指令在表单控件元素上创建双向数据绑定. v-mo ...
- ajax级联实现
效果如下: 选择第一项,第二项.第三项的内容跟着改变. 选择第二项,第三项的内容跟着改变. 第三项则不影响第一项和第二项. 有几点值得提: 1.html到底是前台拼接还是后台拼接. 我选择的是前台拼接 ...
- 双杀 0day 漏洞(CVE-2018-8174)复现
漏洞描述: CVE-2018-8174 是 Windows VBScript Engine 代码执行漏洞. 微软在4月20日早上确认此漏洞,并于5月8号发布了官方安全补丁,对该 0day 漏洞进行了修 ...
- java - 读取,导出 excel文件数据
首先需下载poi java包,添加至构建路径, 写处理方法: import java.io.FileInputStream;import java.io.FileOutputStream;import ...
- java 高并发解决方案
对于我们开发的网站,如果网站的访问量非常大的话,那么我们就需要考虑相关的并发访问问题了.而并发问题是绝大部分的程序员头疼的问题, 但话又说回来了,既然逃避不掉,那我们就坦然面对吧~今天就让我们一起来研 ...
- 使用K2时提示未能加载文件或程序集Microsoft.IdentityModel等
转:http://www.cnblogs.com/dannyli/archive/2012/10/15/2724931.html K2安装成功后,打开workspace管理流程时报错如下图: 未能加载 ...
- 玩转angularJs——通过自定义ng-model,不仅仅只是input可以实现双向数据绑定
体验更优排版请移步原文:http://blog.kwin.wang/programming/angularJs-user-defined-ngmodel.html angularJs双向绑定特性在开发 ...