淺顯而精辟地解說設計模式
什么是設計模式?
設計模式是對軟件設計中出現(xiàn)的典型問題的常規(guī)解決方案。它們就像一個解決典型問題的藍圖,您可以對其進行定制。
我為什么要學習模式?
關于設計模式的好處是,它們是針對常見問題的經(jīng)過嘗試和測試的解決方案。這使您能夠以有效的方式解決在程序中遇到的問題,而不必重新發(fā)明輪子。如果您和您的團隊成員了解模式,它可以幫助提高溝通的效率。
使用模式也有一些缺點。當您了解不同的軟件模式時,您可能會嘗試實現(xiàn)不需要或不是最佳解決方案的模式。另一個可能的缺點是試圖實現(xiàn)一個模式過于字面化,而沒有根據(jù)項目的上下文對其進行定制。
模式分類
設計模式通常分為三類: 創(chuàng)建模式、結(jié)構(gòu)模式和行為模式。
創(chuàng)建模式描述了創(chuàng)建對象的方法,這些方法可以提高代碼重用性和靈活性。
結(jié)構(gòu)模式為如何將對象和類構(gòu)建成更大的結(jié)構(gòu)提供了模式,同時使它們具有適應性和高效性。
行為模式描述了用于有效通信和對象之間責任委托的模式。
讓我們來探索一些更常見的軟件設計模式。
工廠法
Factory 方法解決了創(chuàng)建對象時不必指定所創(chuàng)建的確切類的問題。超類定義了一個創(chuàng)建對象的接口,子類實現(xiàn)了創(chuàng)建對象的特定邏輯。
例如,可以引入一個名為 ShapeFactory 的工廠接口,并具有一個名為 createShape 的方法,該方法返回一個 Shape 類型的對象。具體的實現(xiàn),比如 CircleFactory 和 RectangleFactory,然后將實現(xiàn) createShape 方法來返回 Circle 和 Recangle 類型的對象。
工廠模式的一個優(yōu)點是,您可以通過添加新的子類來引入新的類型,而不必破壞現(xiàn)有的代碼。
單例
Singleton 是一個只允許一個類有一個實例的創(chuàng)建型模式。要創(chuàng)建一個單例類,類的缺省構(gòu)造函數(shù)需要是私有的。這樣可以確保其他類不能調(diào)用單例類上的新方法。不要使用缺省構(gòu)造函數(shù),創(chuàng)建一個靜態(tài)創(chuàng)建方法。如果不存在對象,此方法將調(diào)用私有構(gòu)造函數(shù),否則將返回已存在的緩存對象。
單例類解決的問題是,它確保一個類只有一個實例,并且可以為該實例提供一個全局訪問點。單例類對于緩存、日志記錄和注冊表等類很有幫助。
建造者
Builder 是一個可以讓你一步一步創(chuàng)建復雜對象的創(chuàng)建型模式。這允許使用相同的構(gòu)造代碼來實現(xiàn)不同的類型和表示。
如果存在一個可以有很多變體的類,那么構(gòu)造函數(shù)就會變得非常龐大和混亂。例如,想象一下有很多額外設備(防抱死制動系統(tǒng),加熱座椅,后視攝像頭等)的“汽車”類。與其擁有一個包含所有選項的大型汽車構(gòu)造函數(shù),不如使用構(gòu)造函數(shù)類。構(gòu)建器類可以有一系列構(gòu)造汽車不同變體的方法。例如 buildFrame、 addWheels、 addBrakes、 addRearViewCamera 等等。.
構(gòu)建器模式的優(yōu)點是,在構(gòu)建不同的對象時,可以重用相同的構(gòu)建代碼,而且構(gòu)建代碼與產(chǎn)品的業(yè)務邏輯是隔離的。
適配器
適配器模式是允許具有不同接口的兩個類進行通信的模式。適配器作為類之間的轉(zhuǎn)換器工作,這樣它們就可以一起工作。例如,如果一個類輸出 XML,而另一個類需要 JSON 輸入。然后需要一個適配器來將 XML 轉(zhuǎn)換為 JSON。
代理
代理是一種結(jié)構(gòu)模式,允許您通過創(chuàng)建替代品或占位符來控制對對象的訪問。如果存在不總是運行的服務或資源,代理可以處理服務的初始化。這樣就不需要在所有使用服務的地方復制初始化代碼。
代理模式建議您創(chuàng)建一個具有與原始對象相同接口的新代理類。然后您可以在程序中使用代理對象而不是原始對象。然后,代理將工作委托給原始對象。
使用代理的好處是,您可以控制對原始對象的訪問,而且即使原始對象已關閉,代理也可以工作。
狀態(tài)
狀態(tài)模式在內(nèi)部狀態(tài)更改時處理對象的行為。例如,當對象處于特定狀態(tài)時,某些行為是不允許的。
狀態(tài)模式與有限狀態(tài)機緊密相連。這告訴我們一個程序只能處于一定數(shù)量的狀態(tài)。各個狀態(tài)的行為不同,并非所有的狀態(tài)都可以相互轉(zhuǎn)換。
為了創(chuàng)建封裝狀態(tài)之間轉(zhuǎn)換規(guī)則和狀態(tài)行為的邏輯,條件語句(if、 switch 或者模式匹配)是常見的。如果有很多狀態(tài),這個邏輯就會變得很大,很難維護。
狀態(tài)模式通過為每個狀態(tài)實現(xiàn)類來解決這個問題。每個狀態(tài)類處理自己的行為和轉(zhuǎn)換到新狀態(tài)的邏輯。原始對象(也稱為上下文)通過用新的狀態(tài)對象替換活動狀態(tài)對象來更改狀態(tài)。所有狀態(tài)對象都需要遵循一個公共接口。
策略
策略模式允許在一個抽象下對一系列算法進行分組。這允許運行庫在算法之間切換。
策略模式與狀態(tài)模式非常相似。它不處理不同的狀態(tài),而是處理不同的算法或策略。
例如,谷歌地圖提供了使用汽車、步行、公共交通等方式進行導航的選項。.這些選項使用不同的算法,但都可以在同一個客戶機中使用。
策略模式為不同的策略使用通用接口。原來的類變得獨立于具體的策略。原始類有一個用于存儲策略對象的字段。特定的策略對象負責執(zhí)行算法。客戶端負責選擇正確的算法。
使用策略模式的一個優(yōu)點是,您可以在將來添加額外的算法,而不會使原始類變得混亂。
觀察者
觀察者是一種描述訂閱機制的模式,它允許多個對象在它們觀察到的對象發(fā)生更改時得到通知。
所觀察到的對象通常稱為主題或發(fā)布者。更改發(fā)生時通知的對象稱為訂閱方。YouTube 就是這種觀察者模式的一個例子,每當一個頻道發(fā)布一個新視頻,就會通知關注者。
發(fā)布者類應該具有添加和刪除訂閱者以及通知所有訂閱者的方法。所有訂閱者都應該具有相同的接口和方法,發(fā)布者可以調(diào)用這些接口和方法來通知他們更改。通常,發(fā)布者有一個訂閱者列表,循環(huán)訪問訂閱者,并調(diào)用訂閱者“ update”方法來通知他們發(fā)布者的更改。