一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - C# - 深入解析C#設計模式編程中對建造者模式的運用

深入解析C#設計模式編程中對建造者模式的運用

2021-11-12 15:18LearningHard C#

這篇文章主要介紹了C#設計模式編程中對建造者模式的運用,文中還介紹了在.NET框架下建造者模式編寫思路的實現,需要的朋友可以參考下

示例

我們先來以這樣一個場景引入: 
在電腦城裝機總有這樣的經歷。我們到了店里,先會有一個銷售人員來詢問你希望裝的機器是怎么樣的配置,他會給你一些建議,最終會形成一張裝機單。和客戶確定了裝機配置以后,他會把這張單字交給提貨的人,由他來準備這些配件,準備完成后交給裝機技術人員。技術人員會把這些配件裝成一個整機交給客戶。

不管是什么電腦,它總是由CPU、內存、主板、硬盤以及顯卡等部件構成的,并且裝機的過程總是固定的:

  • 把主板固定在機箱中
  • 把CPU安裝到主板上
  • 把內存安裝到主板上
  • 把硬盤連接到主板上
  • 把顯卡安裝到主板上

但是,每臺兼容機的部件都各不相同的,有些配置高一點,有些配置低一點,這是變化點。對于裝機技術人員來說,他不需要考慮這些配件從哪里來的,他只需要把他們組裝在一起了,這是穩定的裝機流程。要把這種變化的配件和穩定的流程進行分離就需要引入Builder模式。
示例代碼

?
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
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
using System;
 
using System.Collections.Generic;
 
using System.Text;
 
using System.Reflection;
 
 
 
namespace BuilderExemple
 
{
 
  classProgram
 
  {
 
    staticvoid Main(string[] args)
 
    {
 
      ComputerFactory factory = newComputerFactory();
 
      ComputerBuilder office = newOfficeComputerBuilder();
 
      factory.BuildComputer(office);
 
      office.Computer.ShowSystemInfo();
 
      ComputerBuilder game = newGameComputerBuilder();
 
      factory.BuildComputer(game);
 
      game.Computer.ShowSystemInfo();
 
    }
 
  }
 
 
 
  classComputerFactory
 
  {
 
    publicvoid BuildComputer(ComputerBuilder cb)
 
    {
 
      Console.WriteLine();
 
      Console.WriteLine(">>>>>>>>>>>>>>>>>>Start Building " + cb.Name);
 
      cb.SetupMainboard();
 
      cb.SetupCpu();
 
      cb.SetupMemory();
 
      cb.SetupHarddisk();
 
      cb.SetupVideocard();
 
      Console.WriteLine(">>>>>>>>>>>>>>>>>>Build " + cb.Name + " Completed");
 
      Console.WriteLine();
 
    }
 
  }
 
 
 
  abstractclassComputerBuilder
 
  {
 
    protectedstring name;
 
 
 
    publicstring Name
 
    {
 
      get { return name; }
 
      set { name = value; }
 
    }
 
 
 
    protectedComputer computer;
 
 
 
    publicComputer Computer
 
    {
 
      get { return computer; }
 
      set { computer = value; }
 
    }
 
 
 
    public ComputerBuilder()
 
    {
 
      computer = newComputer();
 
    }
 
 
 
    publicabstractvoid SetupMainboard();
 
    publicabstractvoid SetupCpu();
 
    publicabstractvoid SetupMemory();
 
    publicabstractvoid SetupHarddisk();
 
    publicabstractvoid SetupVideocard();
 
  }
 
 
 
  classOfficeComputerBuilder : ComputerBuilder
 
  {
 
    public OfficeComputerBuilder()
 
    {
 
      name = "OfficeComputer";
 
    }
 
 
 
    publicoverridevoid SetupMainboard()
 
    {
 
      computer.Mainboard = "Abit升技LG-95C 主板(Intel 945GC芯片組/LGA 775/1066MHz) ";
 
    }
 
 
 
    publicoverridevoid SetupCpu()
 
    {
 
      computer.Cpu = "Intel 英特爾賽揚D 336 (2.8GHz/LGA 775/256K/533MHz) ";
 
    }
 
 
 
    publicoverridevoid SetupMemory()
 
    {
 
      computer.Memory = "Patriot博帝DDR2 667 512MB 臺式機內存";
 
    }
 
 
 
    publicoverridevoid SetupHarddisk()
 
    {
 
      computer.Harddisk = "Hitachi日立SATAII接口臺式機硬盤(80G/7200轉/8M)盒裝";
 
    }
 
 
 
    publicoverridevoid SetupVideocard()
 
    {
 
      computer.Videocard = "主板集成";
 
    }
 
  }
 
 
 
  classGameComputerBuilder : ComputerBuilder
 
  {
 
    public GameComputerBuilder()
 
    {
 
      name = "GameComputer";
 
    }
 
 
 
    publicoverridevoid SetupMainboard()
 
    {
 
      computer.Mainboard = "GIGABYTE技嘉GA-965P-DS3 3.3 主板(INTEL P965 東莞產)" ;
 
    }
 
 
 
    publicoverridevoid SetupCpu()
 
    {
 
      computer.Cpu = "Intel 英特爾酷睿E4400 (2.0GHz/LGA 775/2M/800MHz)盒裝";
 
    }
 
 
 
    publicoverridevoid SetupMemory()
 
    {
 
      computer.Memory = "G.SKILL 芝奇F2-6400CL5D-2GBNQ DDR2 800 1G*2臺式機內存";
 
    }
 
 
 
    publicoverridevoid SetupHarddisk()
 
    {
 
      computer.Harddisk = "Hitachi日立SATAII接口臺式機硬盤(250G/7200轉/8M)盒裝";
 
    }
 
 
 
    publicoverridevoid SetupVideocard()
 
    {
 
      computer.Videocard = "七彩虹逸彩GT-GD3 UP烈焰戰神H10 顯卡(GeForce 8600GT/256M/DDR3)支持HDMI!";
 
    }
 
  }
 
 
 
  classComputer
 
  {
 
    privatestring videocard;
 
 
 
    publicstring Videocard
 
    {
 
      get { return videocard; }
 
      set { videocard = value; }
 
    }
 
 
 
    privatestring cpu;
 
 
 
    publicstring Cpu
 
    {
 
      get { return cpu; }
 
      set { cpu = value; }
 
    }
 
 
 
    privatestring mainboard;
 
 
 
    publicstring Mainboard
 
    {
 
      get { return mainboard; }
 
      set { mainboard = value; }
 
    }
 
 
 
    privatestring memory;
 
 
 
    publicstring Memory
 
    {
 
      get { return memory; }
 
      set { memory = value; }
 
    }
 
 
 
    privatestring harddisk;
 
 
 
    publicstring Harddisk
 
    {
 
      get { return harddisk; }
 
      set { harddisk = value; }
 
    }
 
 
 
    publicvoid ShowSystemInfo()
 
    {
 
      Console.WriteLine("==================SystemInfo==================");
 
      Console.WriteLine("CPU:" + cpu);
 
      Console.WriteLine("MainBoard:" + mainboard);
 
      Console.WriteLine("Memory:" + memory);
 
      Console.WriteLine("VideoCard:" + videocard);
 
      Console.WriteLine("HardDisk:" + harddisk);
 
    }
 
  }
 
}

代碼說明: 

ComputerFactory是建造者模式的指導者。指導者做的是穩定的建造工作,假設它就是一個技術人員,他只是在做按照固定的流程,把配件組裝成計算機的重復勞動工作。他不知道他現在組裝的是一臺游戲電腦還是一臺辦公用電腦,他也不知道他往主板上安裝的內存是1G還是2G的。呵呵,看來是不稱職的技術人員。

ComputerBuilder是抽象建造者角色。它主要是用來定義兩種接口,一種接口用于規范產品的各個部分的組成。比如,這里就規定了組裝一臺電腦所需要的5個工序。第二種接口用于返回建造后的產品,在這里我們沒有定義抽象方法,反正建造出來的總是電腦。

OfficeComputerBuilder和GameComputerBuilder是具體的建造者。他的工作就是實現各建造步驟的接口,以及實現返回產品的接口,在這里后者省略了。

Computer就是建造出來的復雜產品。在代碼中,我們的各種建造步驟都是為創建產品中的各種配件服務的,Computer定義了一個相對具體的產品,在應用中可以把這個產品進行比較高度的抽象,使得不同的具體建造者甚至可以建造出完全不同的產品。

看看客戶端的代碼,用戶先是選擇了一個具體的Builder,用戶應該很明確它需要游戲電腦還是辦公電腦,但是它可以對電腦一無所知,由銷售人員給出一個合理的配置單。然后用戶讓ComputerFactory去為它組裝這個電腦。組裝完成后ComputerFactory開機,給用戶驗收電腦的配置是否正確。

你或許覺得ComputerBuilder和是抽象工廠模式中的抽象工廠角色差不多,GameComputerBuilder又像是具體工廠。其實,建造者模式和抽象工廠模式的側重點不同,前者強調一個組裝的概念,一個復雜對象由多個零件組裝而成并且組裝是按照一定的標準射順序進行的,而后者強調的是創建一系列產品。建造者模式適用于組裝一臺電腦,而抽象工廠模式適用于提供用戶筆記本電腦、臺式電腦和掌上電腦的產品系列。


建造者模式的定義和類圖
  介紹完了建造者模式的具體實現之后嗎,下面具體看下建造者模式的具體定義是怎樣的。

建造者模式(Builder Pattern):將一個復雜對象的構建于它的表示分離,使得同樣的構建過程可以創建不同的表示。

建造者模式使得建造代碼與表示代碼的分離,可以使客戶端不必知道產品內部組成的細節,從而降低了客戶端與具體產品之間的耦合度,下面通過類圖來幫助大家更好地理清建造者模式中類之間的關系。

深入解析C#設計模式編程中對建造者模式的運用

 

建造者模式的分析
介紹完了建造者模式的具體實現之后,讓我們總結下建造模式的實現要點:

在建造者模式中,指揮者是直接與客戶端打交道的,指揮者將客戶端創建產品的請求劃分為對各個部件的建造請求,再將這些請求委派到具體建造者角色,具體建造者角色是完成具體產品的構建工作的,卻不為客戶所知道。
建造者模式主要用于“分步驟來構建一個復雜的對象”,其中“分步驟”是一個固定的組合過程,而復雜對象的各個部分是經常變化的(也就是說電腦的內部組件是經常變化的,這里指的的變化如硬盤的大小變了,CPU由單核變雙核等)。
產品不需要抽象類,由于建造模式的創建出來的最終產品可能差異很大,所以不大可能提煉出一個抽象產品類。
在前面文章中介紹的抽象工廠模式解決了“系列產品”的需求變化,而建造者模式解決的是 “產品部分” 的需要變化。
由于建造者隱藏了具體產品的組裝過程,所以要改變一個產品的內部表示,只需要再實現一個具體的建造者就可以了,從而能很好地應對產品組成組件的需求變化。

.NET 中建造者模式的實現
  前面的設計模式在.NET類庫中都有相應的實現,那在.NET 類庫中,是否也存在建造者模式的實現呢? 然而對于疑問的答案是肯定的,在.NET 類庫中,System.Text.StringBuilder(存在mscorlib.dll程序集中)就是一個建造者模式的實現。不過它的實現屬于建造者模式的演化,此時的建造者模式沒有指揮者角色和抽象建造者角色,StringBuilder類即扮演著具體建造者的角色,也同時扮演了指揮者和抽象建造者的角色,此時建造模式的實現如下:

?
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
/// <summary>
  /// 建造者模式的演變
  /// 省略了指揮者角色和抽象建造者角色
  /// 此時具體建造者角色扮演了指揮者和建造者兩個角色
  /// </summary>
  public class Builder
  {
    // 具體建造者角色的代碼
    private Product product = new Product();
    public void BuildPartA()
    {
      product.Add("PartA");
    }
    public void BuildPartB()
    {
      product.Add("PartB");
    }
    public Product GetProduct()
    {
      return product;
    }
    // 指揮者角色的代碼
    public void Construct()
    {
      BuildPartA();
      BuildPartB();
    }
  }
  /// <summary>
  /// 產品類
  /// </summary>
  public class Product
  {
    // 產品組件集合
    private IList<string> parts = new List<string>();
    // 把單個組件添加到產品組件集合中
    public void Add(string part)
    {
      parts.Add(part);
    }
    public void Show()
    {
      Console.WriteLine("產品開始在組裝.......");
      foreach (string part in parts)
      {
        Console.WriteLine("組件" + part + "已裝好");
      }
      Console.WriteLine("產品組裝完成");
    }
  }
  // 此時客戶端也要做相應調整
  class Client
  {
    private static Builder builder;
    static void Main(string[] args)
    {
      builder = new Builder();
      builder.Construct();
      Product product = builder.GetProduct();
      product.Show();
      Console.Read();
    }
  }

StringBuilder類扮演著建造string對象的具體建造者角色,其中的ToString()方法用來返回具體產品給客戶端(相當于上面代碼中GetProduct方法)。其中Append方法用來創建產品的組件(相當于上面代碼中BuildPartA和BuildPartB方法),因為string對象中每個組件都是字符,所以也就不需要指揮者的角色的代碼(指的是Construct方法,用來調用創建每個組件的方法來完成整個產品的組裝),因為string字符串對象中每個組件都是一樣的,都是字符,所以Append方法也充當了指揮者Construct方法的作用。


總結
到這里,建造者模式的介紹就結束了,建造者模式(Builder Pattern),將一個復雜對象的構建與它的表示分離,使的同樣的構建過程可以創建不同的表示。建造者模式的本質是使組裝過程(用指揮者類進行封裝,從而達到解耦的目的)和創建具體產品解耦,使我們不用去關心每個組件是如何組裝的。

延伸 · 閱讀

精彩推薦
  • C#C#裁剪,縮放,清晰度,水印處理操作示例

    C#裁剪,縮放,清晰度,水印處理操作示例

    這篇文章主要為大家詳細介紹了C#裁剪,縮放,清晰度,水印處理操作示例,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    吳 劍8332021-12-08
  • C#WPF 自定義雷達圖開發實例教程

    WPF 自定義雷達圖開發實例教程

    這篇文章主要介紹了WPF 自定義雷達圖開發實例教程,本文介紹的非常詳細,具有參考借鑒價值,需要的朋友可以參考下...

    WinterFish13112021-12-06
  • C#C#通過KD樹進行距離最近點的查找

    C#通過KD樹進行距離最近點的查找

    這篇文章主要為大家詳細介紹了C#通過KD樹進行距離最近點的查找,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    帆帆帆6112022-01-22
  • C#C#實現XML文件讀取

    C#實現XML文件讀取

    這篇文章主要為大家詳細介紹了C#實現XML文件讀取的相關代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    Just_for_Myself6702022-02-22
  • C#C#設計模式之Visitor訪問者模式解決長隆歡樂世界問題實例

    C#設計模式之Visitor訪問者模式解決長隆歡樂世界問題實例

    這篇文章主要介紹了C#設計模式之Visitor訪問者模式解決長隆歡樂世界問題,簡單描述了訪問者模式的定義并結合具體實例形式分析了C#使用訪問者模式解決長...

    GhostRider9502022-01-21
  • C#深入解析C#中的交錯數組與隱式類型的數組

    深入解析C#中的交錯數組與隱式類型的數組

    這篇文章主要介紹了深入解析C#中的交錯數組與隱式類型的數組,隱式類型的數組通常與匿名類型以及對象初始值設定項和集合初始值設定項一起使用,需要的...

    C#教程網6172021-11-09
  • C#Unity3D實現虛擬按鈕控制人物移動效果

    Unity3D實現虛擬按鈕控制人物移動效果

    這篇文章主要為大家詳細介紹了Unity3D實現虛擬按鈕控制人物移動效果,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一...

    shenqingyu060520232410972022-03-11
  • C#C# 實現對PPT文檔加密、解密及重置密碼的操作方法

    C# 實現對PPT文檔加密、解密及重置密碼的操作方法

    這篇文章主要介紹了C# 實現對PPT文檔加密、解密及重置密碼的操作方法,非常不錯,具有參考借鑒價值,需要的朋友可以參考下...

    E-iceblue5012022-02-12
主站蜘蛛池模板: 免费看一级大片 | 成人福利在线视频免费观看 | 99ri国产精品 | 污小说h | 99在线免费观看视频 | 欧美国产日韩在线播放 | 国产精品天天看天天爽 | 亚洲图片二区 | 亚洲日本aⅴ片在线观看香蕉 | 精品AV亚洲乱码一区二区 | 王的视频vk | 精品一卡2卡3卡4卡5卡亚洲 | 微福利92合集 | 亚洲国产天堂在线观看 | 亚洲日韩欧美一区二区在线 | 国产精品国产三级国产专区不 | 亚洲免费国产 | 人人九九 | 国产麻豆精品入口在线观看 | 免费国产成人高清视频网站 | 99久久99久久久精品齐齐鬼色 | 久久精品小视频 | 亚洲欧美日韩久久一区 | xxxxx性13一14| 2020精品极品国产色在线观看 | 久久精品国产亚洲AV麻豆欧美玲 | 1313午夜精品久久午夜片 | 好紧好爽的午夜寂寞视频 | voyeur多毛厕所 | 日本四虎影院 | 歪歪视频在线播放无遮挡 | 青青网站| 国色天香社区视频免费高清在线观看 | 日本激情网 | 午夜a一级毛片 | 日韩免费视频播播 | 91久久偷偷做嫩草影院免费看 | china精品对白普通话 | 午夜精品久久久内射近拍高清 | 久久久无码精品亚洲A片软件 | 不卡一区二区三区卡 |