一、 装饰(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. mongo数据排序和分页显示

    数据排序 使用sort()1 升序-1 降序自然排序 数据插入的顺序$natural db.stu.drop(); db.stu.insert({,,"address":" ...

  2. Java并发--CountDownLatch CyclicBarrier ReentrantLock

    CountDownLatch CountDownLatch是一个同步工具类,它允许一个或多个线程一直等待,直到其他线程的操作执行完后再执行.CountDownLatch使用一个数字count初始化,使 ...

  3. 拦截导弹简单版(读入一串整数时getline(cin,s) stringstream is(s);)

    拦截导弹简单版 时间限制: 1 Sec  内存限制: 128 MB提交: 40  解决: 16[提交][状态][讨论版][命题人:外部导入] 题目描述 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系 ...

  4. loadrunner 学习 1 —— 关于loadrunner的安装/破解

    从网上下载了loadrunner 11, .iso格式的镜像文件,百度一下,发现要用专门的软件才能在windows7 下安装 iso,我选的是 软件魔方. 安装完破解时,略有曲折, 主要是要以管理员的 ...

  5. [置顶] STM32的ADC1采集多条通道,可以不使用DMA功能吗?

    类似的问题 为什么我采集5条通道的电压,而采集到的值却都是第一条的呢? 我什么时候需要使用DMA功能? Ⅰ关于ADC的一些知识 STM32的ADC是一种12位逐次逼近型的模拟数字转换器.它有多达18条 ...

  6. 众包高效实用的.NET开源项目

    1.Akka.NET: 概述:更轻松地构建强大的并发和分布式应用. 简介:Akka.NET是一个用于在.NET和Mono上构建高度并发,分布式和容错的事件驱动应用程序的工具包和运行时. 开源地址:ht ...

  7. linux中zookeeper

    linux中zookeeper 安装jdk tar -zxvf jdk-11.0.1_linux-x64_bin.tar.gz -C /usr/src sudo vim /etc/profile 输入 ...

  8. javascript第四节

    闭包: 块级作用域: 私有变量:

  9. 一只小蜜蜂(斐波那契dp)

    有一只经过训练的蜜蜂只能爬向右侧相邻的蜂房,不能反向爬行.请编程计算蜜蜂从蜂房a爬到蜂房b的可能路线数. 其中,蜂房的结构如下所示. Input输入数据的第一行是一个整数N,表示测试实例的个数,然后是 ...

  10. MSSQL列记录合并

    创建表及插入数据 If OBJECT_ID(N'Demo') Is Not Null Begin Drop Table Demo End Else Begin Create Table Demo( A ...