装饰(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)~多功能消息组件的实现
返回目录 为何要设计多功能消息组件 之前写过一篇装饰器模式的文章,感觉不够深入,这次的例子是实现项目中遇到的,所以把它拿出来,再写写,之前也写过消息组件的文章,主要采用了策略模式实现的,即每个项目可以 ...
随机推荐
- vue参考
https://github.com/taylorchen709/vue-admin http://element-cn.eleme.io/#/zh-CN/component/layout https ...
- 【转】c# 判断指定文件是否存在
private void button2_Click(object sender, EventArgs e) { if (File.Exists(@"E:\exists.txt") ...
- The java.util.concurrent Synchronizer Framework笔记
这篇笔记是关于 Doug Lea 的 The java.util.concurrent Synchronizer Framework . 原文地址:http://gee.cs.oswego.edu/d ...
- (转) 读懂IL
引言 转自园子里的一片关于IL的好文,分享的同时,方便自己今后查阅. 原文链接:http://www.cnblogs.com/brookshi/p/5225801.html ------ 略过作者调侃 ...
- Py修行路 python基础 (二十)模块 time模块,random模块,hashlib模块,OS及sys模块
一.前提介绍: 可以开辟作用域的只有类,函数,和模块 for循环 if,else: 不能开辟自己的作用域 避免程序复用和重复调用,将这些写到一个.py文件中,做成一个模块,进行调 ...
- Python3 持久化pickle模块
pickle提供了一个简单的持久化功能.可以将对象以文件的形式存放在磁盘上. 1.pickle.dump(obj, file[, protocol]) 序列化对象,并将结果数据流写入到文件对象中.参数 ...
- day-7心得
面向对象高级语法部分 经典类vs新式类 把下面代码用python2 和python3都执行一下 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 2 ...
- VB.NET使用TagLib#读取MP3中的ID3v2标签
Taglib#是一个为.NET开发的元数据读取类库,为一个开源项目,可以在他们的官网上获取windows版本的源码包或者编译好的类库:http://download.banshee.fm/taglib ...
- Spring Cloud Config 1 (分布式配置中心)
spring cloud config是spring cloud团队创建的一个全新的项目,用来为分布式系统中的基础设施和微服务应用提供集中化的外部配置支持,它分为服务端和客户端两部分. 服务端也被称为 ...
- PHP数据结构之一:PHP数据结构基本概念—数据结构
学习任何一种技术都应该先清楚它的基本概念,这是学习任何知识的起点!本文是讲述数据结构的基本概念,适合对数据结构已经有一定基础的程序员,更是适合想要学习数据结构的code一族!让我们开始PHP数据结构的 ...