1. 程式人生 > >設計模式之創建型匯總

設計模式之創建型匯總

會有 單例模式 runtime tom vat top 可擴展 作用域 只需要

設計模式


創建型

工廠方法模式

定義:定義一個創建對象的接口,但讓實現這個接口的類來決定實例化哪個類,工廠方法讓類的實例化推遲到子類中進行

使用場景

  • 創建對象需要大量重復的代碼

  • 客戶端(應用層)不依賴於產品類實例如何被創建、實現等細節

  • 一個類通過其子類來指定創建哪個對象

  • 當明確地計劃不同條件下創建不同實例時

優點

  • 用戶只需關心所需產品對應的工廠,無須關心創建細節

  • 加入新產品符合開閉原則,提高可擴展性

缺點

  • 類的個數容易過多,增加復雜度

  • 增加了系統的抽象性和理解難度

註意事項

:作為一種創建類模式,在任何需要生成復雜對象的地方,都可以使用工廠方法模式。有一點需要註意的地方就是復雜對象適合使用工廠模式,而簡單對象,特別是只需要通過 new 就可以完成創建的對象,無需使用工廠模式。如果使用工廠模式,就需要引入一個工廠類,會增加系統的復雜度。

源碼用處

  • collection 類的 iterator

抽象工廠模式

定義:提供一個創建一系列相關或相互依賴對象的接口,而無需指定它們具體的類,工廠的工廠

使用場景

  • 系統的產品有多於一個的產品族,而系統只消費其中某一族的產品

  • 客戶端(應用層)不依賴於產品類實例如何被創建、實現等細節

  • 提供一個產品類的庫,所有的產品以同樣的接口出現,從而使客戶端不依賴於具體實現

優點

  • 當一個產品族中的多個對象被設計成一起工作時,它能保證客戶端始終只使用同一個產品族中的對象

  • 具體產品在應用層代碼隔離,無須關心細節

  • 將一個系列的產品族統一到一起創建

缺點

  • 產品族擴展非常困難,要增加一個系列的某一產品,既要在抽象的 Creator 裏加代碼,又要在具體的裏面加代碼

  • 增加了系統的抽象性和理解難度

註意事項:產品族難擴展,產品等級易擴展。

源碼用處

  • jdk:java.sql.connection、java.sql.statement

  • mybatis:SqlSessionFactory

建造者模式

定義:將一個復雜的對象的構建與它的表示分離,使得同樣的構建過程可以創建不同的表示,用戶只需指定需要建造的類型就可以得到它們,建造過程及細節不需要知道

使用場景

  • 如果一個對象有非常復雜的內部結構(很多屬性),想把復雜對象的創建和使用分離。一些基本部件不會變,而其組合經常變化的時候。

優點

  • 易擴展,建造者獨立,一定程度的解耦

  • 封裝性好,創建與使用相分離

  • 便於控制細節風險

缺點

  • 產品必須有共同點,範圍有限制

  • 如內部過於復雜,會有很多的建造類

  • 產品內部發生變化,建造者都要修改,成本較大

註意事項:與工廠模式的區別是:建造者模式更加關註與零件裝配的順序

源碼用處

  • StringBuilder

  • mybatis裏面的SqlSessionFactoryBuilder

單例模式

定義:保證一個類僅有一個實例,並提供一個全局的訪問點

使用場景

  • 想確保任何情況下都絕對只有一個實例

  • 當你想控制實例數目,節省系統資源的時候

優點

  • 在內存裏只有一個實例,減少了內存的開銷,尤其是頻繁的創建和銷毀實例(比如管理學院首頁頁面緩存)。

  • 避免對資源的多重占用(比如寫文件操作)

  • 設置全局訪問點,嚴格控制訪問

缺點

  • 沒有接口,不能繼承

  • 與單一職責原則沖突,一個類應該只關心內部邏輯,而不關心外面怎麽樣來實例化

註意事項:私有構造器,線程安全,延遲加載,序列化和反序列化安全(需要在單例類裏,添加readResolve()方法如:

private Object readResolve(){
return hungrySingleton;
}

),反射Q(解決辦法:在私有構造器裏面,添加判斷,拋出異常,如:

private LazySingleton(){
if(lazySingleton != null){
throw new RuntimeException("單例模式禁止反射調用");
}
}

源碼用處

  • jdk1.8 的 Runtime類(餓漢式):private static Runtime currentRuntime = new Runtime();

  • jdk1.8 的 Desktop(容器式)

  • spring 中的 bean 的作用域 singleton

原型模式

定義:指定原型實例指定創建對象的種類,並且通過拷貝這些原型創建新的對象,不需要知道任何創建的細節,不調用構造函數

使用場景

  • 類初始化消耗較多的資源

  • new產生的一個對象需要非常繁瑣的過程(數據備份、訪問權限等)

  • 構造函數比較復雜

  • 循環體中產生大量的對象時

優點

  • 原型模式性能比直接new一個對象性能高

  • 簡化創建過程

缺點

  • 必須配備克隆方法

  • 對克隆復雜對象或對克隆出的對象進行復雜改造時,容易引入風險

  • 深拷貝、淺拷貝要運用得當

註意事項

  • 深克隆,淺克隆

  • 在實際項目中,原型模式很少單獨出現,一般是和工廠方法模式一起出現,通過 clone 的方法創建一個對象,然後由工廠方法提供給調用者。原型模式已經與 Java 融為渾然一體,大家可以隨手拿來使用。

設計模式之創建型匯總