一、 装饰(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. fragment在水平/垂直时的应用

    直接看代码 public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedIns ...

  2. C#去除数组空格

    static void Main(string[] args) { "}; Console.WriteLine("输出带有空字符串的数组:"); foreach (str ...

  3. ubuntu为什么没有/etc/inittab文件? 深究ubuntu的启动流程分析

    Linux 内核启动 init ,init进程ID是1,是所有进程的父进程,所有进程由它控制. Ubuntu 的启动由upstart控制,自9.10后不再使用/etc/event.d目录的配置文件,改 ...

  4. HTMLTestRunner生成报告 中文展示乱码的问题

  5. 《PHP对象、模式与实践》之高级特性

    高级特性包括:1.静态方法和属性(通过类而不是对象来访问数据和功能)2.抽象类和接口(设计,实现分离)3.错误处理(异常)4.Final类和方法(限制继承)5.拦截器(自动委托)6.析构方法(对象销毁 ...

  6. Deep Learning 学习笔记(1):线性回归( Linear Regression )

    关于DL,由于我是零经验入门, 事实上我是从最简单的ML开始学起, 所以这个系列我也从ML开始讲起. ===============并行分割线================= 一.线性回归 线性回归 ...

  7. python学习——练习题(2)

    """ 题目:企业发放的奖金根据利润提成.利润(I)低于或等于10万元时,奖金可提10%: 利润高于10万元,低于20万元时,低于10万元的部分按10%提成,高于10万元 ...

  8. leetcode908

    int smallestRangeI(vector<int>& A, int K) { int min = INT_MAX; int max = INT_MIN; for (aut ...

  9. form表单中的button按钮

    如果在form表单中 , 存在button元素,button元素就充当了submit的角色

  10. C. Ray Tracing——披着搜索外衣的扩展欧几里得

    [题目大意] 给你一个n*m的矩形,光线从(0,0)出发,沿右上方向以每秒根号2米的速度运动,碰到矩形边界就会反弹(符合物理规律的反弹),询问k个点,这些点都在矩形内部且不在矩形边界上,求光经过这些点 ...