本篇博文,给大家讲解一下装饰模式,还是老样子,有一个简单的例子逐步演绎
一、举例
用一个简单的控制台实现 一个人穿各种各样衣服 的功能
然后我们会很自然的写出一下代码:
先写一个Person类
1 class Person
2 {
3 private string name;
4 public Person(string name)
5 {
6 this.name = name;
7 }
8 public void WearTshirts()
9 {
10 Console.WriteLine("大T恤");
11 }
12 public void WearBigTrouser()
13 {
14 Console.WriteLine("跨裤");
15 }
16 public void WearSneakers()
17 {
18 Console.WriteLine("破球鞋");
19 }
20 public void WearSuit()
21 {
22 Console.WriteLine("西装");
23 }
24 public void WearTie()
25 {
26 Console.WriteLine("领带");
27 }
28 public void WearLeatherShoes()
29 {
30 Console.WriteLine("皮鞋");
31 }
32 public void Show()
33 {
34 Console.WriteLine($"{name}装扮完毕!");
35 }
36 }
然后客户端调用这个Person类
1 static void Main(string[] args)
2 {
3 Person xmw = new Person("小魔王");
4 Console.WriteLine("\n第一种装扮");
5 xmw.WearTshirts();
6 xmw.WearBigTrouser();
7 xmw.WearSneakers();
8 xmw.Show();
9 Console.WriteLine("\n第二种装扮");
10 xmw.WearSuit();
11 xmw.WearTie();
12 xmw.WearLeatherShoes();
13 xmw.Show();
14 Console.ReadKey();
15 }
这样就写完了。
二、演绎
①现在,我各种装扮都写到了Person类中,有这样一个问题,假如,有一天,我新加了一件衣服,比如"皮裤"哈哈,那么,我该怎么办呢?
很多小伙伴就说了,这很容易啊,直接在Person类中增加一个“皮裤”的方法不就完事了吗。
这的确可以解决这个问题,这也是大多数人解决这个问题的方法。但是,真正的高手可以看出里面的弊端。
首先,给大家介绍程序设计中的一个重要原则——开放-封闭原则,这个原则讲的是:软件实体(类,模块,函数等等)应该可以扩展,但是不可修改。也就是说对于扩展是开放的,对于修改是封闭的。
那么,用 修改Person类来解决上述的问题就违背了开放-封闭原则。
那我们该如何解决上述这个问题呢?
于是,我们想到这样一个设计方法:
1 /// <summary>
2 /// Person类
3 /// </summary>
4 class Person
5 {
6 private string name;
7 public Person(string name)
8 {
9 this.name = name;
10 }
11 public void Show()
12 {
13 Console.WriteLine($"{name}装扮完毕");
14 }
15 }
16 /// <summary>
17 /// 服饰抽象类
18 /// </summary>
19 abstract class Finery
20 {
21 public abstract void Show();
22 }
23 //各种服饰子类
24 class TShirts : Finery
25 {
26 public override void Show()
27 {
28 Console.WriteLine("大T恤");
29 }
30 }
31 class BigTrouser : Finery
32 {
33 public override void Show()
34 {
35 Console.WriteLine("跨裤");
36 }
37 }
38 class Sneakers : Finery
39 {
40 public override void Show()
41 {
42 Console.WriteLine("破球鞋");
43 }
44 }
45 class Surt : Finery
46 {
47 public override void Show()
48 {
49 Console.WriteLine("西装");
50 }
51 }
52 class Tie : Finery
53 {
54 public override void Show()
55 {
56 Console.WriteLine("领带");
57 }
58 }
59 class LeatherShoes : Finery
60 {
61 public override void Show()
62 {
63 Console.WriteLine("皮鞋");
64 }
65 }
上述,我们把各种各样的服饰写成单个的类。
客户端:
1 static void Main(string[] args)
2 {
3 Person xmw = new Person("小魔王");
4 Console.WriteLine("\n第一种装扮");
5 Finery dtx = new TShirts();
6 Finery kk = new BigTrouser();
7 Finery pqx = new Sneakers();
8 dtx.Show();
9 kk.Show();
10 pqx.Show();
11 xmw.Show();
12 Console.WriteLine("\n第二种装扮");
13 Finery xz = new Surt();
14 Finery ld = new Tie();
15 Finery px = new LeatherShoes();
16 xz.Show();
17 ld.Show();
18 px.Show();
19 xmw.Show();
20 Console.ReadKey();
21 }
这样的话,如果要增加新的服饰,我只需要增加一个Finery 的子类就可以了。
在这里,我们用到了继承,用到了抽象,也做到了‘服饰’类与‘人’类的分离,的确进步不少,但还存在一些其他的问题。
什么问题呢?我们来看一下这段代码:
1 dtx.Show();
2 kk.Show();
3 pqx.Show();
4 xmw.Show();
怎么看怎么别扭呢。在客户端把穿的各种服饰一个一个的显示出来。这就好比