c#设计模式-建造者模式
意圖
?
?????? 將一個復雜的構建與其表示相分離,使得同樣的構建過程可以創建不同的表示。
?
場景
?
?????? 在電腦城裝機總有這樣的經歷。我們到了店里,先會有一個銷售人員來詢問你希望裝的機器是怎么樣的配置,他會給你一些建議,最終會形成一張裝機單。和客戶確定了裝機配置以后,他會把這張單字交給提貨的人,由他來準備這些配件,準備完成后交給裝機技術人員。技術人員會把這些配件裝成一個整機交給客戶。
?????? 不管是什么電腦,它總是由CPU、內存、主板、硬盤以及顯卡等部件構成的,并且裝機的過程總是固定的:
l???????? 把主板固定在機箱中
l???????? 把CPU安裝到主板上
l???????? 把內存安裝到主板上
l???????? 把硬盤連接到主板上
l???????? 把顯卡安裝到主板上
但是,每臺兼容機的部件都各不相同的,有些配置高一點,有些配置低一點,這是變化點。對于裝機技術人員來說,他不需要考慮這些配件從哪里來的,他只需要把他們組裝在一起了,這是穩定的裝機流程。要把這種變化的配件和穩定的流程進行分離就需要引入Builder模式。
?
示例代碼
?
| 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); ??????? } ??? } } |
代碼執行結果如下圖:
?
?
代碼說明
?
l???????? ComputerFactory是建造者模式的指導者。指導者做的是穩定的建造工作,假設它就是一個技術人員,他只是在做按照固定的流程,把配件組裝成計算機的重復勞動工作。他不知道他現在組裝的是一臺游戲電腦還是一臺辦公用電腦,他也不知道他往主板上安裝的內存是1G還是2G的。呵呵,看來是不稱職的技術人員。
l???????? ComputerBuilder是抽象建造者角色。它主要是用來定義兩種接口,一種接口用于規范產品的各個部分的組成。比如,這里就規定了組裝一臺電腦所需要的5個工序。第二種接口用于返回建造后的產品,在這里我們沒有定義抽象方法,反正建造出來的總是電腦。
l???????? OfficeComputerBuilder和GameComputerBuilder是具體的建造者。他的工作就是實現各建造步驟的接口,以及實現返回產品的接口,在這里后者省略了。
l???????? Computer就是建造出來的復雜產品。在代碼中,我們的各種建造步驟都是為創建產品中的各種配件服務的,Computer定義了一個相對具體的產品,在應用中可以把這個產品進行比較高度的抽象,使得不同的具體建造者甚至可以建造出完全不同的產品。
l???????? 看看客戶端的代碼,用戶先是選擇了一個具體的Builder,用戶應該很明確它需要游戲電腦還是辦公電腦,但是它可以對電腦一無所知,由銷售人員給出一個合理的配置單。然后用戶讓ComputerFactory去為它組裝這個電腦。組裝完成后ComputerFactory開機,給用戶驗收電腦的配置是否正確。
l???????? 你或許覺得ComputerBuilder和是抽象工廠模式中的抽象工廠角色差不多,GameComputerBuilder又像是具體工廠。其實,建造者模式和抽象工廠模式的側重點不同,前者強調一個組裝的概念,一個復雜對象由多個零件組裝而成并且組裝是按照一定的標準射順序進行的,而后者強調的是創建一系列產品。建造者模式適用于組裝一臺電腦,而抽象工廠模式適用于提供用戶筆記本電腦、臺式電腦和掌上電腦的產品系列。
?
何時采用
?
l???????? 從代碼角度來說, 如果你希望分離復雜類型構建規則和類型內部組成,或者希望把相同的構建過程用于構建不同類型的時候可以考慮使用建造者模式。
l???????? 從應用角度來說, 如果你希望解耦產品的創建過程和產品的具體配件,或者你希望為所有產品的創建復用一套穩定并且復雜的邏輯的時候可以考慮使用建造者模式。
?
實現要點
?
l???????? 對象的構建過程由指導者完成,具體的組成由具體建造者完成,表示與構建分離。
l???????? 建造者和指導者是建造者模式的關鍵點,如果進行合并或省略就可能會轉變到模版方法模式。
l???????? 如果對象的建造步驟是簡單的,并且產品擁有一致的接口可以轉而使用工廠模式。
?
注意事項
?
l???????? 返回產品的方法是否必須,是否一定要在抽象建造者中有接口根據實際情況而定。如果它們有統一的接口可以在抽象建造者中體現這個抽象方法,如果沒有統一的接口(比如,生產毫無關聯的產品)則可以在具體建造者中各自實現這個方法,如果創建的產品是一種產品,那么甚至可以省略返回產品的接口(本文的例子就是這樣)。
原文鏈接:http://www.cnblogs.com/lovecherry/archive/2007/10/07/915986.html
總結
以上是生活随笔為你收集整理的c#设计模式-建造者模式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [linux] 查看网络丢包信息
- 下一篇: C# ManualResetEvent的