介绍
本文引用《大话设计模式》第六章节的内容进行学习分析,仅供学习使用
需求:做一个人物换装,换装用字符串打印表示即可。
需求分析
看到这个需求我第一反应是将每一件衣服、裤子、鞋子划分为单个对象,每一个对象有自己的算法也好处理方式也好,采用策略模式持有属性简单工厂的方式去实现,但是看完这篇文章发现如果按照这种方式去设计架构的话在后面的调用上可能会出现不稳定的问题,比如中途卡顿情况出现的话可能会出现只有上衣?或者只有裤子?都可能会发生,那么这个时候可能有人会想到建造者模式,但是建造者模式是稳定发生的,比如规定好了先穿衣服在穿裤子最后在穿鞋子,但是这都不符合正常人的逻辑,毕竟有人先穿裤子,也有人喜欢先穿上衣,所以这种稳定的建造者模式不可取,那么这里用装饰模式的方式去实现
什么是装饰模式
装饰模式(Decorator):动态的给一个对象添加一些额外的指责,就增加功能来说,装饰模式要比生成子类更加灵活。
Component是定义了一个对象接口,可以给这些对象动态的添加指责。ConcreteComponent是定义了一个具体对象。Decorator装饰抽象类,继承了Component,从外类来扩展Component的功能,对于Component来说,是无需知道Decorator的存在的。至于ConcreteDecorator就是具体的装饰对象,起到给Component添加指责的功能。还有一个好处就是在后期需要添加新衣服的时候,只需要添加新类即可,同样遵守了单一指责原则和开放封闭原则。
代码如下:
using System;
namespace Decorator
{
/// <summary>
/// Component.定义一个对象的接口 动态的给对象添加指责
/// </summary>
public abstract class Component
{
public abstract void Operation();
}
}
using System;
namespace Decorator
{
/// <summary>
/// Concrete component.定义了一个具体的对象 这里也可以给对象添加指责
/// </summary>
public class ConcreteComponent : Component
{
public override void Operation()
{
Console.WriteLine("具体对象的操作");
}
}
}
using System;
namespace Decorator
{
/// <summary>
/// Decorator.装饰抽象类 从外类来扩展Component类的功能 对于Component来说是无需知道Decorator的存在
/// </summary>
public class Decorator : Component
{
protected Component component;
/// <summary>
/// Sets the component.设置Component
/// </summary>
/// <param name="component">Component.</param>
public void SetComponent(Component component)
{
this.component = component;
}
public override void Operation()
{
if (component != null)
{
component.Operation();
}
}
}
}
using System;
namespace Decorator
{
public class ConcreteDecoratorA : Decorator
{
private string AddState;
public override void Operation()
{
base.Operation();
AddState = "ConcreteDecoratorA";
Console.WriteLine("具体服饰对象A的操作");
}
}
public class ConcreteDecoratorB : Decorator
{
public override void Operation()
{
base.Operation();
AddBehaviour();
Console.WriteLine("具体服饰对象B的操作");
}
public void AddBehaviour()
{
}
}
}
装饰模式实际就是使用上图的SetComponent来对对象进行包装的。这样使得每个装饰对象的实现和如何使用这个对象分开了,每个装饰对象只关心自己的功能即可,不需要关心如何被添加到对象链中。
注意
如果只有一个ConceteComponent类而没有抽象的Component类,那么Decorator类可以是Concrete的一个字类,同样道理如果ConcreteDecorator只有一个,就没有必要写一个单独的Decorator类,而可以把ConcreteDecorator与Decorator合并为一个类。
总结
装饰模式是为已有功能动态添加更多功能的一种方式,当系统需要新功能的时候,是向旧功能中添加新代码,这些新加的代码通常装饰了原有类的核心指责或主要行为。在主类中加入了新的字段、方法或者逻辑,从而增加了主类的复杂度,而这些新加入的东西仅仅是为了满足一些只在某种特定情况下才会执行的特殊行为的需要。这时候装饰者就是一个不错的选择,它把每一个装饰的功能放在单独的类中,并让这个类装饰它想要装饰的对象,因此,在特殊情况下,客户端代码在运行时就可以根据需要有选择的、有顺序的去包装对象。
装饰模式的优点就是把类中装饰功能从类中去掉,简化了原有的类。有效的把核心指责和装饰功能区分开来。而且可以去除装饰类中重复的逻辑。