对某一个类动态的添加不同的功能,我们可能会给写不同的功能类让其来继承,这样的话就会有很多的类变得冗余过多,装饰者模式就是解决这个问题的
Compont对象时一个具体的对象接口,可以给对象动态的添加职责
ConcreteComponent是定义了一个具体的对象,也可以给这个对象添加一些职责
Decorator:用来扩展Component类的功能
相应的模板
abstarct class Component { public abstarct void Operation(); }
class ConcreteComponent:Component { public override void Operation() { console.writerline(""); } }
abstract class Decorator:Component { proctect Component component; public void SetComment(Component component) { this.compoent=component; } public override void Operation() { console.writerline(""); } }
class ConcreteDecoratorA:Decorator { private string addedState; public override void Operation() { base.Operation(); addState="New State"; Console.writerline("具体的对象A的操作"); } }
class ConcreteDecoratorB:Decorator { public override void Operation() { base.Operation(); AddedBehavior(); Console.writerline("具体的对象A的操作"); } private void AddedBehavior() { } }
ConcreteDecoratorA类中独有的的字段addState,对原有的addState进行装饰,ConcreteDecoratorB独有的方法AddedBehavior对对象进行装饰
通过SetComponent进行包装
ConcreteComponent c=new ConcreteComponent(); ConcreteDecoratorA d1=new ConcreteDecoratorA(); ConcreteDecorateoB d2=new ConcreteDecoratorB(); d1.SetComponent(c); d1.Operation(); d2.SetComponent(c); d2.Operation();
先新建一个手机例子,手机定义了只有Print的功能
public abstract class Phone { public abstract void Print(); }
public class ApplePhone:Phone { public override void Print() { Console.WriteLine("苹果手机"); Console.WriteLine("可惜我现在只有Print的功能"); } }
这是我们实例化抽象的Phone一个ApplePhone手机
现在我们假设我们的ApplePhone有了Print的方法,并且再这个项目中的很多款手机都实现了抽象的Phone并且只有Print手机,
随着科技的进步,ApplePhone手机的Print方法满足不了客户的需求,手机要增加Playmusic的功能方法了
那么问题来了,我们是不可能去更改抽象的Phone手机类,因为这样的更改就会也要更改子类的很多方法,这样又违背了开闭的原则,所以我们这里又可以借助装饰者模式来解决这个问题
增加一个装饰者类
public abstract class Decorator : Phone { private Phone phone; public Decorator(Phone phone) { this.phone = phone; } public override void Print() { if (phone != null) { phone.Print(); } } }
现在我们来增加PlayMusic的功能类
class PlayMusic : Decorator { public PlayMusic(Phone p) : base(p) { } public override void Print() { base.Print(); AddPlayMusic(); } public void AddPlayMusic() { Console.WriteLine("现在苹果手机有了播放音乐的功能"); Console.WriteLine("播放音乐!lalala..."); } }
Phone phone = new ApplePhone(); Decorator applePhoneWithPlayMusic = new PlayMusic(phone); applePhoneWithPlayMusic.Print();
下面让我们看看装饰者模式具体在哪些情况下使用,在以下情况下应当使用装饰者模式: