Python建造者模式案例運行原理解析
建造者模式的適用范圍:想要創(chuàng)建一個由多個部分組成的對象,而且它的構(gòu)成需要一步接一步的完成。只有當(dāng)各個部分都完成了,這個對象才完整。建造者模式表現(xiàn)為復(fù)雜對象的創(chuàng)建與表現(xiàn)相分離,這樣,同一個過程就有不同的表現(xiàn)。
假設(shè)我們要創(chuàng)建一個HTML頁面生成器就可以使用建造者模式。該模式中,有兩個參與者:建造者(builder)和指揮者(director)。建造者負責(zé)創(chuàng)建負責(zé)對象的各個組成部分。在HTML例子中,這些組成部分包括:頁面標(biāo)題、文本標(biāo)題、內(nèi)容主體和頁腳。指揮者使用一個建造者實例控制建造的過程。對于HTML示例,這里指調(diào)用建造者的函數(shù)設(shè)置頁面標(biāo)題、文本標(biāo)題等。使用不同的建造者實例讓我們可以創(chuàng)建不同的HTML頁面,而無需更換指揮者代碼。
1. 現(xiàn)實生活中的例子
快餐店使用的即是建造者設(shè)計模式。即使存在多種漢堡包(經(jīng)典款、奶酪漢堡包等等)和不同的包裝(大、中、小盒子等),準備一個漢堡包及打包(盒子或者紙袋)的流程都是一樣的。兩種漢堡包的區(qū)別在于表現(xiàn),而不在于建造的過程。指揮者是出納員,將需要準備什么餐品的指令傳達給工作人員,即建造者。
2. 軟件的例子
本文一開始提到的HTML例子,在django-widgy中得到了實際應(yīng)用。django-widgy是一個Django的第三方樹編輯器擴展,可用作內(nèi)容管理系統(tǒng)。它包含一個網(wǎng)頁構(gòu)建器,用來創(chuàng)建具有不同布局的HTML頁面。
django-query-builder是另一個基于建造者模式的Django第三方擴展庫,該擴展庫可用于動態(tài)地構(gòu)建SQL查詢。使用它,我們可以控制一個查詢的方方面面,并能創(chuàng)建不同種類的查詢。
3. 應(yīng)用案例
如果我們知道一個對象必須經(jīng)過多個步驟來創(chuàng)建,并且要求同一個構(gòu)造過程可用于產(chǎn)生不同的表現(xiàn),就可以使用建造者模式。例如頁面生成器、文檔轉(zhuǎn)換器以及用戶界面等等。
工廠模式與建造者模式的區(qū)別在于工廠模式以單個步驟創(chuàng)建對象,而建造者模式以多個步驟創(chuàng)建對象,且?guī)缀跏冀K使用一個指揮者。一些有針對性的建造者模式實現(xiàn)并未使用指揮者,如Java的StringBuffer。
另一個區(qū)別是,在工廠模式下,會立即返回一個創(chuàng)建好的對象;而在建造者模式下,僅需要時客戶端代碼才顯示地請求指揮者返回最終的對象。
新電腦類比的例子可能會有助于區(qū)分建造者模式和工廠模式。假設(shè)你想買一臺新電腦,如果決定購買一臺特定的預(yù)配置的電腦型號,例如,最新的蘋果1.4GHz Mac mini,則是使用工廠模式。所有硬件的規(guī)格都已經(jīng)有制造商預(yù)先確定,制造商不用向你咨詢就知道自己該做些什么,它們通常接收的僅僅是單條指令。代碼如下
MINI14 = '1.4GHz Mac mini' class AppleFactory: class MacMini14: def __init__(self): self.memory = 4 # 單位為GB self.hdd = 500 # 單位為GB self.gpu = 'Intel HD Graphics 5000' def __str__(self): info = ('Model: {}'.format(MINI14),'Memory: {}GB'.format(self.memory),'Hard Disk: {}GB'.format(self.hdd),'Graphics Card: {}'.format(self.gpu)) return '\n'.join(info) def build_computer(self, model): if (model == MINI14): return self.MacMini14() else: print("I dont't know how to build {}".format(model)) if __name__ == '__main__': afac = AppleFactory() mac_mini = afac.build_computer(MINI14) print(mac_mini)
另一個選擇是購買一臺定制的PC。假若這樣,使用的即是建造者模式。你是指揮者,向制造商(建造者)提供指令說明心中理想的電腦規(guī)格。
class Computer: def __init__(self, serial_number): self.serial = serial_number self.memory = None # 單位為GB self.hdd = None # 單位為GB self.gpu = None def __str__(self): info = ('Memory: {}GB'.format(self.memory),'Hard Disk: {}GB'.format(self.hdd),'Graphics Card: {}'.format(self.gpu)) return '\n'.join(info) class ComputerBuilder: def __init__(self): self.computer = Computer('AG23385193') def configure_memory(self, amount): self.computer.memory = amount def configure_hdd(self, amount): self.computer.hdd = amount def configure_gpu(self, gpu_model): self.computer.gpu = gpu_model class HardwareEngineer: def __init__(self): self.builder = None def construct_computer(self, memory, hdd, gpu): self.builder = ComputerBuilder()① [step for step in (self.builder.configure_memory(memory),self.builder.configure_hdd(hdd),self.builder.configure_gpu(gpu))] @property def computer(self): return self.builder.computer def main(): engineer = HardwareEngineer() engineer.construct_computer(hdd=500, memory=8, gpu='GeForce GTX 650 Ti') computer = engineer.computer print(computer) if __name__ == '__main__': main()
基本的變化是引入了一個建造者ComputerBuilder、一個指揮者HardwareEngineer以及一步接一步裝配一臺電腦的過程,這樣現(xiàn)在就支持不同的配置了(注意, memory、 hdd及gpu是形參并未預(yù)先設(shè)置)。
4. 小結(jié)
本章中,我們學(xué)習(xí)了如何使用建造者設(shè)計模式。可以在工廠模式(工廠方法或抽象工廠)不適用的一些場景中使用建造者模式創(chuàng)建對象。在以下幾種情況下,與工廠模式相比,建造者模式是更好的選擇。
- [ ] 想要創(chuàng)建一個復(fù)雜對象(對象由多部分組成,且創(chuàng)建對象的過程結(jié)果許多步驟,也許這些步驟還需要特定的順序)。
- [ ] 要求一個對象有許多不同的表現(xiàn),并希望對象的構(gòu)造與表現(xiàn)得耦合度低
- [ ] 想要在不同得時間創(chuàng)建對象
我們看到了快餐店如何將建造者模式用于準備食物,兩個第三方Django擴展包( django-widgy和django-query-builder)各自如何使用建造者模式來生成HTML頁面和動態(tài)的SQL查詢。我們重點學(xué)習(xí)了建造者模式與工廠模式之間的區(qū)別,通過對預(yù)先配置(工廠)電腦與客戶定制(建造者)電腦進行訂單類比來理清這兩種設(shè)計模式。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Python學(xué)習(xí)之私有函數(shù),私有變量及封裝詳解
私有函數(shù)與私有變量中的私有就是獨自擁有、不公開、不分享的意思。放到函數(shù)與變量中就是獨自擁有的函數(shù)與獨自擁有的變量,并且不公開。本文將通過示例詳細講解Python中的私有函數(shù)、私有變量及封裝,感興趣的可以學(xué)習(xí)一下2022-03-03解決TensorFlow訓(xùn)練模型及保存數(shù)量限制的問題
這篇文章主要介紹了解決TensorFlow訓(xùn)練模型及保存數(shù)量限制的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-03-03安裝pytorch報錯torch.cuda.is_available()=false問題的解決過程
最近想用pytorch,因此裝了pytorch,但是碰到了問題,下面這篇文章主要給大家介紹了關(guān)于安裝pytorch報錯torch.cuda.is_available()=false問題的解決過程,需要的朋友可以參考下2022-05-05淺談Python中進程的創(chuàng)建與結(jié)束
這篇文章主要介紹了淺談Python中進程的創(chuàng)建與結(jié)束,但凡是硬件,都需要有操作系統(tǒng)去管理,只要有操作系統(tǒng),就有進程的概念,就需要有創(chuàng)建進程的方式,需要的朋友可以參考下2023-07-07關(guān)于Python 中的時間處理包datetime和arrow的方法詳解
這篇文章主要介紹了關(guān)于Python 中的時間處理包datetime和arrow的相關(guān)知識,本文通過實例代碼給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下2020-03-03Python+matplotlib實現(xiàn)填充螺旋實例
這篇文章主要介紹了Python+matplotlib實現(xiàn)填充螺旋實例,具有一定借鑒價值,需要的朋友可以參考下2018-01-01