一、 装饰(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);
}
}

三、 装饰模式应当在什么情况下使用

在以下情况下应当使用装饰模式:

  1. 需要扩展一个类的功能,或给一个类增加附加责任。
  2. 需要动态地给一个对象增加功能,这些功能可以再动态地撤销。
  3. 需要增加由一些基本功能的排列组合而产生的非常大量的功能,从而使继承关系变得不现实。

  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)模式的更多相关文章

  1. 装饰(Decorator)模式

    1.装饰(Decorator)模式    动态给一个对象添加一些额外的职责.就增加功能来说,装饰模式比生成子类更为灵活.Component是定义一个对象接口.可以给这些对象动态地添加职责.Concre ...

  2. 《Head First 设计模式》ch.3 装饰(Decorator)模式

    设计原则 类应该对修改关闭,对扩展开放(开放-关闭原则).在每个地方使用开放-关闭原则是一种浪费,也没有必要,因为这通常会引入新的抽象层次,增加代码复杂度.需要把注意力集中在设计中最有可能改变的地方. ...

  3. Java 实现装饰(Decorator)模式

    在Java在.io反映非常多类包下是典型的装饰格局,例如: new BufferedOutputStream(OutputStream out) new BufferedInputStream(Inp ...

  4. 设计模式C++描述----10.装饰(Decorator)模式

    一. 举例 我之前做过一个文件系统就叫 MyFileSys 吧,后来的话,客户想加入一些附加功能,比如压缩.加密.杀毒之类的操作,这些附加操作没有先后顺序,比如你可以先压缩再加密,也可以先杀毒再压缩, ...

  5. 九、结构模式之装饰(Decorator)模式

    装饰模式又叫包装模式,装饰模式以客户端透明的方式扩展对象的功能,是继承关系的一个替代方案.装饰模式可以在不使用创造更多的子类的情况下,将对象的功能加以扩展. 装饰模式结构图如下: 其包含的角色就分为: ...

  6. Java与模式:装饰(Decorator)模式

    装饰模式使用被装饰类的一个子类的实例.把client的调用委派到被装饰类,装饰模式的关键在于这样的扩展是全然透明的.   装饰模式在Java种使用也非常广泛,比方我们在又一次定义button.对话框等 ...

  7. Java 装饰器模式详解

    转载请注明出处:http://blog.csdn.net/zhaoyanjun6/article/details/56488020 前言 在上面的几篇文章中,着重介绍了Java 中常见的 IO 相关知 ...

  8. 设计模式(三):“花瓶+鲜花”中的装饰者模式(Decorator Pattern)

    在前两篇博客中详细的介绍了"策略模式"和“观察者模式”,今天我们就通过花瓶与鲜花的例子来类比一下“装饰模式”(Decorator Pattern).在“装饰模式”中很好的提现了开放 ...

  9. 设计模式(九)装饰者模式(Decorator Pattern)

    一.引言 在软件开发中,我们经常想要对一类对象添加不同的功能,例如要给手机添加贴膜,手机挂件,手机外壳等,如果此时利用继承来实现的话,就需要定义无数的类,如StickerPhone(贴膜是手机类).A ...

  10. 说说设计模式~装饰器模式(Decorator)~多功能消息组件的实现

    返回目录 为何要设计多功能消息组件 之前写过一篇装饰器模式的文章,感觉不够深入,这次的例子是实现项目中遇到的,所以把它拿出来,再写写,之前也写过消息组件的文章,主要采用了策略模式实现的,即每个项目可以 ...

随机推荐

  1. python 安装相关命令-汇总

    Microsoft Windows [版本 10.0.14393] (c) 2016 Microsoft Corporation.保留所有权利. C:\Windows\system32>pyth ...

  2. (转)Oracle游标使用全解

    -- 声明游标:CURSOR cursor_name IS select_statement --For 循环游标 --(1)定义游标 --(2)定义游标变量 --(3)使用for循环来使用这个游标 ...

  3. java代码反转toCharAT()的用法

    总结:反转注意for循环里面的变化 package clientFrame; //字符串反转 public class we { public static void main(String[] ar ...

  4. Java-Maven-Runoob:Maven 构建 & 项目测试

    ylbtech-Java-Maven-Runoob:Maven 构建 & 项目测试 1.返回顶部 1. Maven 构建 & 项目测试 在上一章节中我们学会了如何使用 Maven 创建 ...

  5. python3+ros+telnet+telnetlib

    利用python3的telnetlib模块 远程登录ros,输入帐号密码,然后执行命令,并导出结果到txt文本: 不过实际操作这种方式不行,因为telnet导出来的文本文件,带颜色编码,根本无法看哦. ...

  6. Python类(二)-类的继承

    单继承 #-*- coding:utf-8 -*- __author__ = "MuT6 Sch01aR" class People: def __init__(self,name ...

  7. PCA主成分分析 ICA独立成分分析 LDA线性判别分析 SVD性质

    机器学习(8) -- 降维 核心思想:将数据沿方差最大方向投影,数据更易于区分 简而言之:PCA算法其表现形式是降维,同时也是一种特征融合算法. 对于正交属性空间(对2维空间即为直角坐标系)中的样本点 ...

  8. Delphi PDF

    llPDFLib,TPDFDocument 2016开始开源. procedure TForm2.Button1Click(Sender: TObject); var lPdf : TPdfDocum ...

  9. Java多线程-线程的同步(同步方法)

    线程的同步是保证多线程安全访问竞争资源的一种手段.线程的同步是Java多线程编程的难点,往往开发者搞不清楚什么是竞争资源.什么时候需要考虑同步,怎么同步等等问题,当然,这些问题没有很明确的答案,但有些 ...

  10. Basics

    [Basics] 1.You can declare multiple constants or multiple variables on a single line, separated by c ...