设计模式学习之路——Builder 生成器模式

     生成器模式有点类似于抽象工厂模式,两者都返回由许多方法和对象组成的类。它们之间的主要差别是,抽象工厂返回的是一系列相关的类,而生成器是根据提供给它的数据一步一步地构建一个复杂的对象。

动机:

在软件系统中,有时候面临着“一个复杂对象”的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定。

如何应对这种变化?如何提供一种“封装机制”来隔离出“复杂对象的各个部分”的变化,从而保持系统中的“稳定构建算法”不随着需求改变而改变?

意图:

将一个复杂对象的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。

——《设计模式》GoF

结构:

clip_image002

协作:

clip_image002[5]

 

代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
using System;
using System.Collections.Generic;
using System.Text;
 
namespace Builder
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("true: 中式风格房屋,false:西式风格房屋");
            string Input = Console.ReadLine();
            try
            {
                HouseBuilder builder = ClienManger.builder(bool.Parse(Input));
                House chinaHouse = ClienManger.CreateHouse(builder);
                chinaHouse.Show();
            }
            catch
            {
                Console.WriteLine("输入错误!");
            }
         
 
            Console.ReadKey();
 
        }
    }
 
    public class House
    {
        
 
        private List<string> door = new List<string>();
 
        public List<string> Door
        {
            get { return door; }
            set { door = value; }
        }
 
        private List<string> windows = new List<string>();
 
        public List<string> Windows
        {
            get { return windows; }
            set { windows = value; }
        }
 
        private string wall;
 
        public string Wall
        {
            get { return wall; }
            set { wall = value; }
        }
        private string floor;
 
        public string Floor
        {
            get { return floor; }
            set { floor = value; }
        }
 
 
 
        public void Show()
        {
            Console.WriteLine(Door.Count.ToString() + "个" + Door[0].ToString());
            Console.WriteLine(Wall);
            Console.WriteLine(Windows.Count.ToString() + "个" + Windows[0].ToString());
            Console.WriteLine(Floor);
        }
 
    }
 
    public abstract class HouseBuilder
    {
        public abstract void BuildDoor();
 
        public abstract void BuildWall();
 
        public abstract void BuildWindows();
 
        public abstract void BuildFloor();
 
        public abstract House GetHouse();
    }
 
    public class ClienManger
    {
 
        public static House CreateHouse(HouseBuilder builder)
        {
 
            builder.BuildDoor();
            builder.BuildFloor();
            builder.BuildWall();
            builder.BuildWindows();
 
            return builder.GetHouse();
        }
 
        public static HouseBuilder builder(bool bl)
        {
            if (bl)
            {
                return new ChinaHouseBuilder();
            }
            else
            {
                return new EuroHouseBuilder();
            }
        }
    }
 
 
 
    public class ChinaHouseBuilder : HouseBuilder
    {
        private House chinaHouse = new House();
 
        public override void BuildDoor()
        {
            chinaHouse.Door.Add("门(中国风格)");
            chinaHouse.Door.Add("门(中国风格)");
        }
 
 
        public override void BuildWall()
        {
            chinaHouse.Wall = "墙(中国风格)";
        }
 
 
        public override void BuildWindows()
        {
            chinaHouse.Windows.Add("窗(中国风格)");
            chinaHouse.Windows.Add("窗(中国风格)");
        }
 
        public override void BuildFloor()
        {
            chinaHouse.Floor = "地板(中国风格)";
        }
 
        public override House GetHouse()
        {
            return chinaHouse;
        }
    }
 
 
    public class EuroHouseBuilder : HouseBuilder
    {
        private House EuroHouse = new House();
 
        public override void BuildDoor()
        {
            EuroHouse.Door.Add("门(欧洲风格)");
        }
 
        public override void BuildWall()
        {
            EuroHouse.Wall = "墙(欧洲风格)";
        }
 
 
        public override void BuildWindows()
        {
            EuroHouse.Windows.Add("窗(欧洲风格)");
        }
 
        public override void BuildFloor()
        {
            EuroHouse.Floor = "地板(欧洲风格)";
        }
 
        public override House GetHouse()
        {
            return EuroHouse;
        }
    }
}

 

Builder 模式的几个要点:

1.Builder 模式主要用于“分步骤构建一个复杂的对象”。在这其中“分步骤”是一个稳定的算法,而复杂对象的各个部分则经常变化。

2.变化点在哪里,封装哪里—— Builder模式主要在于应对“复杂对象各个部分”的频繁需求变动。其缺点在于难以应对“分步骤构建算法”的需求变动。

3. Abstract Factory模式解决“系列对象”的需求变化,Builder模式解决“对象部分”的需求变化。Builder模式通常和Composite模式组合使用。

posted on   Melou  阅读(426)  评论(0编辑  收藏  举报
努力加载评论中...

点击右上角即可分享
微信分享提示