装饰模式

来源:互联网 发布:js防水涂料配方 编辑:程序博客网 时间:2024/04/25 16:36

           写一个给人搭配不同的服饰的系统,比如类似QQ、网络游戏或论坛都有的Avatar系统。如何开发?

         大多的程序初学者的想法是抽象出一个Person类,在Person类中封装各种方法如戴帽子、穿衬衣、穿西装、穿黑皮鞋等方法。尽管这样可以满足当前的功能需求能装扮出一个衣着打扮让一个程序员满意的人,可是当系统到了用户那里发现用户对当前的衣着不满意要求修改一下装扮,此时就需要把系统拿回去修改代码,增加修改一些方法比如打领带、戴手套等等。改一次也就罢了,过几天用户再看当前装扮有不顺眼了,还得需要把系统拿回去修改代码。这样在违背开放封闭原则的情况下开发出来的系统在后期的维护以及功能扩展上就出现了很大的麻烦,几乎就不易进行维护和功能扩展。而装饰者模式就是建立在遵循开放封闭的原则下的,在不更改源代码的情况下对原有类进行功能扩展。

         装饰模式又叫装饰者模式,装饰模式是在不必改变原类文件和使用继承的情况下,动态的扩展一个对象的功能。它是通过创建一个包装对象,也就是用装饰来包裹真实的对象。

        装饰模式UML类图:

        

        代码示例:

Component提供了一个接口,通过这个接口可以实现功能扩展

using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace 装饰模式{    abstract class Component    {        public abstract void Show();    }}

Person被装饰类继承于Component

using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace 装饰模式{    //抽象一个人类    class Person:Component    {        private string name;       public Person()        {        }       public Person(string name)       {           this.name=name;       }                    public override void Show()       {           Console.Write("装扮的{0}",name);           Console.ReadLine();       }    }}

抽象装饰类Finery,继承于Component,从外类来扩展Component的功能

using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace 装饰模式{    //抽象一个服饰类继承人类    class Finery:Component    {        protected Component component;        public void Decorator(Component component)        {            this.component = component;        }        public override void Show()        {            if (component != null)            {                component.Show();            }        }    }}

具体装饰类:

using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace 装饰模式{    //抽象一个裤子类继承服饰类    class Trouser:Finery    {        public override void Show()        {            Console.Write("牛仔裤");            base.Show();        }    }}using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace 装饰模式{    //抽象一个鞋类继承服饰类    class Shoes:Finery    {        public override void Show()        {            Console.Write("拖鞋");            base.Show();        }    }}using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace 装饰模式{    //抽象一个衬衫类继承服饰类    class BigTshirt:Finery    {        public override void Show()        {                       Console.Write("大衬衫");            base.Show();        }    }}

装饰模式的特点:

        1.             装饰对象和被装饰对象都有相同的接口,目的有利于客户端可以以和被装饰对象相同的方式和装饰对象交互,从而实现功能的扩展。从代码中来看此接口为Show()方法。

        2.             装饰对象包含一个被装饰对象的引用。抽象装饰类Finery中引用被装饰类Component。

        3.             装饰对象接受所有来自客户端的请求,并把这些请求转发给被装饰对象。抽象装饰类Finery的Show()方法利用if (component != null){component.Show();}将请求转发给被装饰对象。

        4.             装饰对象可以在转发这些请求之前或以后增加一些附加功能。这样就确保了在运行时不用修改给定对   象的结构就可以在外部增加附加的功能。在面向对象的设计中,通常是通过继承来实现对给定类的功能的扩展。装饰对象中的Show方法在将请求转发前都增加了附件功能,如BigTshirt类在请求转发base.Show();之前增加了Console.Write("大衬衫");

作者信息详见:http://leimengyuanlian.blog.163.com/

原创粉丝点击