【装饰模式】
装饰模式是利用component来对对象进行包装。每个装饰对象的实现就和如何使用这个对象分离开了,每个装饰对象只关心自己的功能,不需要关心如何被添加到对象链当中
【介绍】
-
主要解决:一般的,我们为了拓展一个类经常使用继承方法实现,由于继承为类引入静态特征,并且随着扩展共能的增多,子类会很多
-
何时使用:在不想增加很多子类的情况下扩展类
-
如何解决:将具体功能职责划分,同时继承装饰模式
-
关键代码:
1、component类充当抽象角色,不应该具体实现
2、修饰类引用和继承component类,具体拓展类重写父类方法
-
优点:装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承一个替代模式,装饰模式可以动态扩展一个实现类的功能
-
缺点:多层装饰比较复杂
【实现】
Comonent是定义一个对象接口,可以给这些对象动态地添加职责。ConcreteComponent是定义了一个具体的对象,也可以给这个对象添加一些职责。Decorator,装饰抽象类,继承Component从外来来扩展conponent类的功能,但对于Component来说,是无需知道Decorator的存在的。至于ConcreteDecorator就是具体的装饰对象,起到给Component添加职责的功能
一个更容易理解的实例
装饰模式为已有类动态附加额外的功能就像是LoL和王者荣耀游戏中,英雄的升级一样。每次英雄升级都会附加一个额外技能点去学习技能。具体的英雄就是Concretecomponent,技能栏就是装饰器Decorator,每个技能就是ConcreteDecorator
步骤一:创建一个接口
abstract class Component
{
public abstract void Operation();
}
步骤二:创建实现接口的实体类
//ConcreateComponent
class ConcreateComponent :Component
{
public override void Operation()
{
Console.WriteLine("具体对象的操作");
}
}
步骤三:创建component接口的抽象装饰类
abstract class Decorator:Component
{
protected Component component;
public void SetComponent(Component component)//设置Component
{
this.component = component;
}
public override void Operation()
{
if (component !=null)
{
component.Operation();
}
}
}
步骤四:创建具体的装饰对象类
abstract class Decorator:Component
{
protected Component component;
public void SetComponent(Component component)//设置Component
{
this.component = component;
}
public override void Operation()
{
if (component !=null)
{
component.Operation();
}
}
}
class ConcreteDecoratorA:Decorator
{
private string addedState;//本类独有功能,以区别于ConcreteDecoratorB
public override void Operation()
{
base.Operation();//首先运行原component的operation(),再执行本类的功能,,如addedstate,相当于对原component进行了装饰
addedState = "new state";
Console.WriteLine("具体装饰对象A的操作");
}
}
class ConcreteDecoratorB : Decorator
{
public override void Operation()
{
base.Operation();
AddedBehavior();
Console.WriteLine("具体装饰对象B的操作");
}
private void AddedBehavior()//本类独有的方法
{
}
}
步骤五:客户端代码
static void Main(string[] args)
{
ConcreateComponent c = new ConcreateComponent();
ConcreteDecoratorA d1 = new ConcreteDecoratorA();
ConcreteDecoratorB d2 = new ConcreteDecoratorB();
d1.SetComponent(c);
d2.SetComponent(d1);
d2.Operation();
//装饰的方法是:首先用concretecomponent实例化对象c,然后用concreteDecoratorA的实例化对象d1来包装c
//再用ConcreteDecoratorB的对象d2来包装d1,最终执行d2的operation()
Console.Read();
}