我的设计模式之旅(4)——生成器(建造者)模式Builder
Builder模式也是創(chuàng)建型模式中的一種。主要用來應(yīng)對(duì)構(gòu)成復(fù)雜但構(gòu)成結(jié)構(gòu)和順序相對(duì)穩(wěn)定的對(duì)象的創(chuàng)建工作。目的是省去在對(duì)象發(fā)生變化時(shí),需要修改代碼中每一處對(duì)象創(chuàng)建的地方,應(yīng)用這種模式,可以在一個(gè)復(fù)雜對(duì)象的內(nèi)部結(jié)構(gòu)(由許多其他子對(duì)象構(gòu)成的結(jié)構(gòu))發(fā)生變化時(shí),僅需要對(duì)對(duì)象有所修改,而復(fù)雜對(duì)象與其他的對(duì)象之間的關(guān)系、行為不需要進(jìn)行修改。
其實(shí)這就是這個(gè)創(chuàng)建型模式應(yīng)用的動(dòng)機(jī):在軟件系統(tǒng)中,有時(shí)面臨著一個(gè)復(fù)雜對(duì)象的創(chuàng)建工作,其通常由各個(gè)部分的子對(duì)象用一定的算法構(gòu)成;由于需求的變化,這個(gè)復(fù)雜對(duì)象的各個(gè)部分經(jīng)常面臨著劇烈的變化,但是將它們組合在一起的算法卻相對(duì)穩(wěn)定。
GOF:
將一個(gè)復(fù)雜對(duì)象的構(gòu)建與其表示相分離,使得同樣的構(gòu)建過程可以創(chuàng)建不同的表示。
下面舉一個(gè)例子,來說明這種應(yīng)用,比如說買電腦中的裝機(jī),根據(jù)消費(fèi)者不同的需求,我們要提供不同品牌不同配置的電腦。
裝機(jī)器就像Builder模式描述的一樣,組裝成機(jī)器的方法(即用子對(duì)象構(gòu)建對(duì)象的算法)是穩(wěn)定的,但是根據(jù)客戶的需求可能對(duì)機(jī)器現(xiàn)有配置要求升級(jí),則只是子對(duì)象發(fā)生了變化,但是這不影響極其的組裝方法。
定義組裝成電腦需要的設(shè)備,這里為了代碼量少一些,簡化了電腦的構(gòu)建,粗略的分為CPU、主板、內(nèi)存、硬盤、鍵盤、鼠標(biāo)。首先構(gòu)建它們對(duì)應(yīng)的抽象類。
???? // 電腦
???? public abstract class Computer
???? {
???? }
?
???? // CPU
???? public abstract class CPU
???? {
???? }
???? // 主板
???? public abstract class Mainboard
???? {
???? }
???? // 內(nèi)存
???? public abstract class Memory
???? {
???? }
???? // 硬盤
???? public abstract class Harddisk
???? {
???? }
???? // 鍵盤
???? public abstract class Keyboard
???? {
???? }
???? // 鼠標(biāo)
???? public abstract class Mouse
???? {
???? }
然后,就可以定義構(gòu)建組裝電腦需要的配件的抽象方法。
???? public abstract class ComputerBuilder
???? {
???????? public abstract void BuildCPU();
???????? public abstract void BuildMainboard();
???????? public abstract void BuildMemory();
???????? public abstract void BuildHarddisk();
???????? public abstract void BuildKeyboard();
???????? public abstract void BuildMouse();
?
???????? public abstract Computer GetComputer();
???? }
這里僅提供了一種品牌機(jī)的標(biāo)準(zhǔn)配置IBM。這時(shí)就可以來構(gòu)建我們實(shí)際需要的IBM配件(實(shí)際子對(duì)象)了。
???? // IBM電腦
???? public class IBMComputer : Computer
???? {
???? }
?
???? // IBMCPU
???? public class IBMCPU : CPU
???? {
???? }
???? // IBM主板
???? public class IBMMainboard : Mainboard
???? {
???? }
???? // IBM內(nèi)存
???? public class IBMMemory : Memory
???? {
???? }
???? // IBM硬盤
???? public class IBMHarddisk : Harddisk
???? {
???? }
???? // IBM鍵盤
???? public class IBMKeyboard : Keyboard
???? {
???? }
???? // IBM鼠標(biāo)
???? public class IBMMouse : Mouse
???? {
???? }
到這里我們就需要定義,組裝IBM配件的方法了。為了簡單,這里又定義了一個(gè)用來存儲(chǔ)實(shí)際需要的配件集合,用來存儲(chǔ)我們構(gòu)建出來的配件(子對(duì)象)。
???? public class AssemblyComputer
???? {
???????? // 組裝起來的電腦配件
???????? ArrayList accessories = new ArrayList();
?
???????? public void Add(string part)
???????? {
????????????? accessories.Add(part);
???????? }
?
???????? public void ShowDetails ()
???????? {
????????????? Console.WriteLine( "Computer Accessories: " );
?
????????????? foreach(string part in accessories)
?????????????????? Console.WriteLine(part);
???????? }
???? }
這時(shí)我們的ComputerBuilder方法和集成自它的實(shí)際構(gòu)建方法IBMComputerBuilder就需要有所修改,返回一個(gè)我們建立的輔助信息存儲(chǔ)類型的對(duì)象AssemblyComputer。以下為修改后的IBM電腦子對(duì)象構(gòu)建類。
???? public class IBMComputerBuilder : ComputerBuilder
???? {
???????? AssemblyComputer ac = new AssemblyComputer();
?
???????? public override void BuildCPU()
???????? {
????????????? ac.Add("IBMCPU");
???????? }
???????? public override void BuildMainboard()
???????? {
????????????? ac.Add("IBMMainboard");
???????? }
???????? public override void BuildMemory()
???????? {
????????????? ac.Add("IBMMemory");
???????? }
???????? public override void BuildHarddisk()
???????? {
????????????? ac.Add("IBMHarddisk");
???????? }
???????? public override void BuildKeyboard()
???????? {
????????????? ac.Add("IBMKeyboard");
???????? }
???????? public override void BuildMouse()
???????? {
????????????? ac.Add("IBMMouse");
???????? }
?
???????? public override AssemblyComputer GetComputer()
???????? {
????????????? return ac;
???????? }
???? }
相應(yīng)的抽象類也做修改。
???? public abstract class ComputerBuilder
???? {
???????? public abstract void BuildCPU();
???????? public abstract void BuildMainboard();
???????? public abstract void BuildMemory();
???????? public abstract void BuildHarddisk();
???????? public abstract void BuildKeyboard();
???????? public abstract void BuildMouse();
?
???????? public abstract AssemblyComputer GetComputer();
???? }
最后,我們定這個(gè)電腦的配置類,就是這臺(tái)電腦的實(shí)際配置。
???? public class ComputerConfiguration
???? {
???????? public static AssemblyComputer CreateComputer(ComputerBuilder computerbuilder)
???????? {
????????????? computerbuilder.BuildCPU();
????????????? computerbuilder.BuildMainboard();
????????????? computerbuilder.BuildMemory();
????????????? computerbuilder.BuildHarddisk();
????????????? computerbuilder.BuildKeyboard();
????????????? computerbuilder.BuildMouse();
?
????????????? return computerbuilder.GetComputer();
???????? }
???? }
其中的CreateComputer方法就是構(gòu)建了一個(gè)電腦的實(shí)際配置例子。這里有一點(diǎn)需要強(qiáng)調(diào)的就是,這臺(tái)電腦需要的配件是穩(wěn)定的,需要CPU、主板、內(nèi)存、硬盤、鍵盤、鼠標(biāo)。至于具體需要什么牌子的,很可能客戶就不要IBM的鍵盤鼠標(biāo),而需要一套羅技的鍵盤和鼠標(biāo),這時(shí)只要修改我們IBM的構(gòu)建類,或者是添加一個(gè)新的自定義電腦配置類,然后在這個(gè)自定義構(gòu)建類中定義我們需要的具體配件,而這些配件(子對(duì)象)構(gòu)建出來的電腦對(duì)象的構(gòu)建過程是不變的。
這樣,我們?cè)诳蛻舫绦蛑惺褂枚x好的對(duì)象時(shí)可以使用下面的代碼。
???? AssemblyComputer ac = ComputerConfiguration.CreateComputer(new IBMComputerBuilder());
???? ac.ShowDetails();
???? Console.ReadLine();
首先定一個(gè)電腦配置,然后使用一個(gè)需要的配置的生成器,最后將電腦配置呈現(xiàn)出來。
得到執(zhí)行結(jié)果:
Computer Accessories:
IBMCPU
IBMMainboard
IBMMemory
IBMHarddisk
IBMKeyboard
IBMMouse
?
看到這段代碼可能大家還是感覺有新的配置后在維護(hù)的時(shí)候仍然需要修改new IBMComputerBuilder()這里,我們可以使用反射機(jī)制來解決這種問題,這樣就解決了擴(kuò)展上不許重新進(jìn)行編譯的問題。如果以前的有所修改那就直接替換掉相應(yīng)的DLL程序集就可以了。方便了以后的維護(hù)擴(kuò)展工作。
?
?
轉(zhuǎn)載于:https://www.cnblogs.com/Bear-Study-Hard/archive/2006/10/24/538606.html
總結(jié)
以上是生活随笔為你收集整理的我的设计模式之旅(4)——生成器(建造者)模式Builder的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: HTTP调试之保持连接状态(微软知识库文
- 下一篇: [导入]创建、查询、修改带名称空间的 X