装饰者模式,我刚看到这个模式的时候,我的脑海里第一反应是已经很经典的广告语:人靠衣装,美靠亮装.思想上移
一点就是装饰模式,就是对某个东西进行装饰,对某个功能进行附加,从而得到新的功能.
现在我们来学习也一下装饰模式!
装饰模式(Decorator):动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为
灵活
设计原理:
1.多用组合,少用继承
继承的子类,实际上需要编译期确定下来,这满足不了需要在运行内才能确定对象的情况。而组合却可以比继承灵
活得多,可以在运行期才决定某个对象。
2.类应设计的对扩展开放,对修改封闭,遵循开放---封闭原则.
类图:
Component(被装饰对象超类):定义对象的接口,可以给这些对象动态地添加职责.
ConcreteComponent(具体被装饰对象):定义具体的对象,Decortor可以给它增加额外的职责.
Decorator(装饰者抽象类):维护一个指向Component实例的引用,并定义了与Component一致的接口
ConcreDecorator(具体装饰者):给内部具体被装饰对象增加具体的职责.
要点:
1.装饰者和被装饰对象有相同的超类型(抽象类和接口统称).
2可以用一个或者多个装饰者包装对象
3.装饰者可以在所委托被装饰者的行为之前或之后,加上自己的行为,以达到特定的目的.
4.对象可以在任何时候被装饰,所以可以在运行时动态的,不限量的而用你喜欢的装饰者来装饰对象.
5.装饰模式中使用继承的关键是想达到装饰者和被装饰对象的类型匹配,而不是火的其行为.
6.装饰者一般对组件的客户是透明的,除非客户程序依赖于组件的具体类型,在实际项目中可以根据需要为装饰者添加新
的行为,做到"半透明"装饰者
7.适配器模式的用意是改变对象的接口而不一定改变对象的性能,而装饰模式的用意是保持接口而增加对象的职责.
实现代码:
namespace 装饰模式
{
///
/// Component类,定义一个对象接口,可以给这些对象动态地添加职责
///
///
abstract class Component
{
public abstract void Operation();
}
///
/// ConcreteComponent类,定义一个具体的对象,也可以给这个对象添加一些职责
///
class ConcreteComponent : Component
{
public override void Operation()
{
Console.WriteLine("具体对象的操作");
}
}
///
/// Decorator类,装饰抽象类,继承了Component,从外类来扩展Component类的功能,
///
///
abstract class Decorator : Component
{
protected Component component;
public void SetComponent(Component component)
{
this.component = component;
}
public override void Operation()
{
if (component != null)
{
component.Operation();
}
}
}
///
/// ConcreteDecoratorA,具体的装饰对象,起到给Component添加职责的功能
///
class ConcreteDecoratorA : Decorator
{
private string addedState;
public override void Operation()
{
base.Operation();
addedState = "New State";
Console.WriteLine("具体装饰对象A的操作");
}
}
///
/// ConcreteDecoratorB,具体的装饰对象,起到给Component添加职责的功能
///
///
class ConcreteDecoratorB : Decorator
{
public override void Operation()
{
base.Operation();
AddedBehavior();
Console.WriteLine("具体装饰对象B的操作");
}
private void AddedBehavior()
{
}
}
///
/// Main 函数,程序入口
///
class Program
{
static void Main(string[] args)
{
ConcreteComponent c = new ConcreteComponent();
ConcreteDecoratorA d1 = new ConcreteDecoratorA();
ConcreteDecoratorB d2 = new ConcreteDecoratorB();
d1.SetComponent(c);
d2.SetComponent(d1);
d2.Operation();
Console.Read();
}
}
}
装饰模式的特点:
1.装饰对象和真实对象有相同的接口,这样客户端对象就可以喝真实对象相同的方式和装饰交互
2.装饰对象包含一个真实对象的索引
3.装饰对象接受所有的来自客户端的请求,它吧这些请求转发给真实的对象.
4.装饰对象可以在转发这些请求以前或以后增加一些附加功能.
优点:
1.装饰模式与继承关系的目的都是要扩展对象的功能,但是Decorator可以提供比继承更多的灵活性.
2.通过使用不同的具体装饰类以及这些装饰类的排序组合,设计师可以创造出很多不同行为的组合.
缺点:
1.这些比继承更加灵活机动的特征,也同时意味着更加多的复杂性.
2.装饰模式会导致设计中出现许多小类,如果过度使用,会使程序变得很复杂.
3.装饰模式是针对抽象组件(Component)类型编辑,但是,如果你要针对具体组件编程时,就应该重新考虑你的应用架构,
以及装饰者是否适合.当然也可以改变组件接口,增加新的公开的行为,实现"半透明"的装饰者模式,在实际项目中要做
出最佳选择.
使用情况:
1,需要扩展一个类的功能,或给一个类添加附加职责.
2.需要动态的给一个对象添加功能,这些功能可以再动态的撤销.
3.需啊哟增加由一些基本功能的排列组合二产生的非常大的功能,从而使继承关系变得不现实.
4.当不能采用生成子类的方法进行扩充时,一种情况是,可能大量独立的扩展,为支持每一种组合激昂产生大量的子类,使
得子类数目呈爆炸性增长.另一种情况可能是因为类定义被隐藏,或类定义不能生成子类.