设计模式-装饰模式

来源:互联网 发布:拉法叶舰案 知乎 编辑:程序博客网 时间:2024/05/22 13:24

这几天又重新看了大话设计模式这本书,想总结一下常用的设计模式,并且借助书上生动形象的例子,加上自己的一点理解。
装饰模式:动态的给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活!
下面是装饰模式的类图:

自己的理解:说得通俗一点,装饰模式就是为了解决对程序功能的扩展的问题而演变而来的设计模式,就比如说一个穿衣服的程序,衣服有很多种类,一种类型的衣服可以用一个类来表示,它们的父类是服饰类,服饰类的父类可以是人这个大类,比如一个人要穿衣服,那么过程可以是这样:先穿上内裤,再穿上牛仔裤,然后穿上T恤,最后穿上外套,那么这个穿衣服的过程就可以用装饰模式来进行理解,因为每穿上一件衣服,就是对人进行一次装饰,如果用代码来展现装饰的过程的话可以是这样:

//Component类abstract class Component{    public abstract void Operation();}//ConcreteComponent类class ConcreteComponent:Component{    public override void Operation(){        Console.WriteLine("具体对象的操作");       }}//Decorator类abstract class Decorator:Component{    protected Component component;    public void SetComponent(Component component){        this.component = component;//根据参数的不同来调用具体子类对象的方法    }}//ConcreteDecoratorA类class ConcreteDecoratorA:Decorator{    private string addedState;//本类独有的功能,区别于B类    public override void Operation(){        base.Operation();//首先运行的是原Component的operation,再执行本类的功能,相当于对原Component进行了装饰        addedState = "new state";        Console.WriteLine("具体装饰对象A的操作");    }}//ConcreteDecoratorB类class ConcreteDecoratorB:Decorator{    public override void Operation(){        base.Operation();//首先运行的是原Component的operation,再执行本类的功能,相当于对原Component进行了装饰        AddedBehavior();        Console.WriteLine("具体装饰对象B的操作");    }    //本类独有的功能,以区别于类A    private void AddedBehavior(){}}
//客户端代码static void main(string[] args){    ConcreteComponent c = new ConcreteComponent();    ConcreteDecoratorA d1 = new ConcreteDecoratorA();    ConcreteDecoratorB d2 = new ConcreteDecoratorB();    //下面开始装饰了,装饰的方法是首先用ConcreteComponent实例化对象c,然后用ConcreteDecoratorA的实例化对象d1来包装c,再用ConcreteDecoratorB的实例化对象d2来包装d1,最终执行d2的Operation    d1.SetComponent(c);    d2.SetComponnet(d1);    d2.Operation();}

这样的话,每个装饰对象的实现就和如何使用这个对象分开了,每个装饰对象只关心自己的功能,不需要关心如何被添加到对象链当中。
问题:为什么要使用装饰模式,而不使用继承?
原因有几点:
1.如果需要对一个类进行多次修改的话,那么使用继承将会导致继承链过长,后续的阅读以及维护会非常不方便,如果使用装饰模式的话,那么各个装饰的功能之间互为平等的关系,都是装饰类的子类。
2.如果使用继承来进行程序功能的扩展,那么添加新的功能时要先把原来的东西复制一份到新的类中,然后再新的子类中开始写新的功能,如果使用装饰模式的话,那么只需要在原来的类的基础上进行一点小小的增加新的功能的装饰而已,而需要再做重复的工作,并且装饰的顺序是可以随意修改的,就好像人穿衣服一样,可以先穿上外套,然后再穿上内衣,顺序可以再客户端进行调用的时候根据需要进行修改,如果使用继承的话,要调整添加功能的顺序,那么需要改变类与类之间的继承关系,那样修改的代价是很大的,所以很多时候使用装饰模式要比使用继承要好!

1 0
原创粉丝点击