首页 > 代码库 > 【笔记】设计模式——装饰者模式

【笔记】设计模式——装饰者模式

实现一个类似QQavator功能的代码

1、原始实现

 1  //存在的问题:
 2     //1、wear*方法出现重复代码,可以重构;实质上为代码结构一致,输出内容相同,可以通过在定义一个基类,在基类中定义抽象的Wear*,在子类中重写;
 3     //2、倘若需求中新增某种服饰,需要修改Person类代码,不符合开放——封闭原则;
 4     //3、客户端中代码暴露了具体装饰细节,理想情况下只需要提供装饰顺序,装饰细节封装起来;
 5     class Person
 6     {
 7         private string name;
 8         private List<string> clothing=new List<string>();
 9         public Person(string name)
10         {
11             this.name = name;
12             clothing.Add("裸体帅哥一枚");
13         }
14         public void WearJeans()
15         {
16             clothing.Add("犀利哥牌——破洞牛仔裤");
17         }
18         public void WearRedTshirt()
19         {
20             clothing.Add("犀利哥牌——墨绿T恤");
21         }
22         public void WearShoes()
23         {
24             clothing.Add("犀利哥牌——牛皮靴子");
25         }
26         public void Show()
27         {
28 
29             Console.WriteLine("大家好,请叫我帅哥{0},今天精心打扮了下,你看我这打扮潮流不?", name);
30             foreach (var item in clothing)
31             {
32                 Console.WriteLine("{0}", item);
33             }
34         }
35 
36         public static void Main(string[] args)
37         {
38             Person person = new Person("犀利哥");
39             person.WearRedTshirt();
40             person.WearJeans();
41             person.WearShoes();
42             person.Show();
43         }

二 改进代码

  

 1  //分析:
 2     //1、问题1解决,使用运行时的多态;
 3     //2、问题2解决,增加新的服饰,继承之;
 4     //3、问题3解决,装饰细节在客户端隐藏为一个Wear方法,客户端仅仅需要搭建起装饰链;
 5     //4、面向对象特征:继承、运行时的多态、里氏原则使用(41行代码)统一了子类同样操作的代码、
 6     //5、Console.WriteLine还是存在子类中重复,能否进一步优化?
 7     //6、客户端与超类、子类均存在联系,能否有必要使用工厂模式?
 8     class Person
 9     {
10         protected string name;
11         public Person()
12         {
13         }
14         public Person(string name)
15         {
16             this.name = name;
17         }
18         public virtual void Wear()
19         {
20             Console.WriteLine("大家好,请叫我帅哥{0},今天精心打扮了下,你看我这打扮潮流不?", name);
21         }
22        
23     }
24    
25     class ComponetA : Person
26     {
27         protected Person com = null;
28          public void  SetComponetA(Person com)
29         {
30             if (com!=null)
31             {
32                 this.com = com;
33             }
34         }
35         public override void Wear()
36         {
37             if (com!=null)
38             {
39                 com.Wear();
40             }
41         }
42         
43     }
44     class Jeans : ComponetA
45     {
46         public override void Wear()
47         {
48             base.Wear();
49            Console.WriteLine("犀利哥牌——破洞牛仔裤");
50         }
51     }
52     class Shoes : ComponetA
53     {
54         public override void Wear()
55         {
56             base.Wear();
57             Console.WriteLine("犀利哥牌——牛皮靴子");
58         }
59     }
60     class RedTshirt : ComponetA
61     {
62         public override void Wear()
63         {
64             base.Wear();
65             Console.WriteLine("犀利哥牌——墨绿T恤");
66         }
67         
68     }
69     class  programmer
70     {
71         public static void Main(string[] args)
72         {
73             Person person = new Person("犀利哥");
74             Jeans jeans = new Jeans();
75             Shoes shoes = new Shoes();
76             RedTshirt redTshirt = new RedTshirt();
77             jeans.SetComponetA(person);
78             shoes.SetComponetA(jeans);
79             redTshirt.SetComponetA(shoes);
80             redTshirt.Wear();
81         }
82     }

三、总结  

1、设计模式解决什么问题?
答:装饰模式把“类中装饰功能从类中搬移去除,这样可以简化原有的类”、“有效地把类的核心职责和装饰功能区分开了。而且可以去除相关的装饰逻辑”;


2、通过什么手段达到效果?
答:装饰模式将一个个欲装饰的功能放在单独的类中,达到容易拓展的效果;使用运行时多态把子类中相同的装饰逻辑统一抽离在基类当中,避免了重复代码;


3、应用场景以及约束条件?
答:需要为已有功能动态添加更多功能时候;
约束条件:装饰类彼此之间独立;装饰顺序很重要(相较于建造者模式,不稳定);


4、符合面向对象哪几条原则?
答:里氏替换、开放-封闭、单一职责;


5、不使用设计模式的代码弊端在哪?
答:见代码


6、改变需求,对使用设计模式的代码的健壮性、可维护性、可拓展性检验;