所谓装饰,就是一些对象给主体对象做陪衬。这是我的理解。好比说我的办公桌,需要电脑、电话、文件夹、盆栽等作为装饰。那么,办公桌就是一个主体对象,电脑、电话等装饰品就是那些做陪衬的对象。这些办公用品准备好了,该怎么摆放到办公桌上呢?可以有多种方案。而且,我可以随时往办公桌上增加一支签字笔,增加一枚公章等等。
目前,可归纳如下:
A主体对象:办公桌
B装饰者:电脑、电话、文件夹、盆栽、签字笔、公章
C装饰者可以装饰主体对象,即B可以装饰A
什么是装饰模式?一个标准的定义是:动态地将责任附加到对象上。若要扩展功能,装饰者提供了比基础更有弹性的替代方案。
根据我的理解,装饰模式可以这样定义:能够动态地为对象添加功能,同时不会对类进行修改。
对于上面的UML类图,我们可以发现装饰模式的两个要点:
1.装饰者(办公用品)需要知道装饰对象(桌子)。(UML类图的聚合关系)
2.装饰对象(办公桌)需要把一系列装饰行为交给装饰者(办公用品),让装饰者帮忙装饰,因此用到了继承。
在办公桌的装饰过程中,办公桌的装饰交给另一个对象来处理,办公桌不需要去管装饰这个过程。也就是把自身的一些行为交给别人来完成,而且这样有个明显的好处就是,这些处理顺序可以改变。可以先摆好电脑,再装上电话,也可以先装个电话在摆好电脑,它们的顺序可以变换。下面是装饰模式的简单的编码实现:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DecorateTest
{
//桌子
public abstract class Desk
{
public abstract void Decorate();
}
//办公桌
public class officeDesk : Desk
{
public override void Decorate()
{
Console.WriteLine(“办公桌已经交给Decoretor来装饰了”);
}
}
//装饰者
public class Decorator : Desk
{
private Desk desk;
//需要知道装饰对象,对应UML中的聚合
public void setDecorate(Desk desk)
{
this.desk = desk;
}
//装饰对象把装饰这个行为交给我来处理了
public override void Decorate()
{
if (desk != null)
{
desk.Decorate();
}
}
}
//电脑
public class Computer : Decorator
{
public override void Decorate()
{
base.Decorate();
Console.WriteLine(“电脑已经装饰摆放好了”);
}
}
//电话
public class Telephone : Decorator
{
public override void Decorate()
{
base.Decorate();
Console.WriteLine(“电话已经摆放好了”);
}
}
//公章
public class Seal : Decorator
{
public override void Decorate()
{
base.Decorate();
Console.WriteLine(“公章已经放好了”);
}
}
class Program
{
static void Main(string[] args)
{
//对办公桌进行装饰
officeDesk office = new officeDesk();
Computer computer = new Computer();
Telephone telephone = new Telephone();
Seal seal = new Seal();
//装饰顺序:电脑、电话、公章
computer.setDecorate(office);
telephone.setDecorate(computer);
seal.setDecorate(telephone );
seal.Decorate();
Console.ReadLine();
}
}
}