創建型設計模式簡介

      網友投稿 867 2022-05-30

      總覽

      在軟件工程中,設計模式描述了軟件設計中最常遇到的問題的既定解決方案。 它代表了經驗豐富的軟件開發人員經過長期反復試驗而形成的最佳實踐。

      在 Erich Gamma、John Vlissides、Ralph Johnson 和 Richard Helm(也稱為 Gang of Four 或 GoF)于 1994 年出版《設計模式:可重用的面向對象軟件的元素》一書后,設計模式開始流行。

      在本文中,我們將探討創建設計模式及其類型。 我們還將查看一些代碼示例并討論這些模式適合我們設計的情況。

      創建型設計模式

      創建型設計模式關注對象的創建方式。 它們通過以受控方式創建對象來降低復雜性和不穩定性。

      new 運算符通常被認為是有害的,因為它會將對象分散到整個應用程序中。 隨著時間的推移,由于類變得緊密耦合,因此更改實現變得具有挑戰性。

      創建設計模式通過將客戶端與實際初始化過程完全分離來解決這個問題。

      在本文中,我們將討論四種創建型設計模式:

      單例 - 確保在整個應用程序中最多只存在一個對象實例

      工廠方法——創建幾個相關類的對象,而不指定要創建的確切對象

      抽象工廠——創建相關依賴對象的族

      Builder - 使用循序漸進的方法構建復雜對象

      現在讓我們詳細討論這些模式。

      單例設計模式

      雖然Singleton模式是由GoF引入的,但是最初的實現在多線程場景中是有問題的。

      所以在這里,我們將遵循一種更優化的方法,即使用靜態內部類:

      public class Singleton { private Singleton() {} private static class SingletonHolder { public static final Singleton instance = new Singleton(); } public static Singleton getInstance() { return SingletonHolder.instance; } }

      在這里,我們創建了一個包含 Singleton 類實例的靜態內部類。 它僅在有人調用 getInstance() 方法而不是在加載外部類時創建實例。

      這是 Singleton 類的一種廣泛使用的方法,因為它不需要同步,是線程安全的,強制執行延遲初始化并且樣板代碼相對較少。

      另外,請注意構造函數具有私有訪問修飾符。 這是創建 Singleton 的要求,因為公共構造函數意味著任何人都可以訪問它并開始創建新實例。

      什么時候使用單例設計模式

      對于創建成本高的資源(如數據庫連接對象)

      將所有記錄器保持為單例是一種很好的做法,這可以提高性能

      提供對應用程序配置設置的訪問的類

      包含以共享模式訪問的資源的類

      工廠方法設計模式

      工廠設計模式或工廠方法設計模式是 Java 中最常用的設計模式之一。

      根據 GoF 的說法,這種模式“定義了一個用于創建對象的接口,但讓子類決定實例化哪個類。 Factory 方法允許類將實例化推遲到子類”。

      該模式通過創建一種虛擬構造函數將初始化類的責任從客戶端委托給特定的工廠類。

      為了實現這一點,我們依賴于為我們提供對象的工廠,隱藏了實際的實現細節。 使用通用接口訪問創建的對象。

      在本例中,我們將創建一個 Polygon 接口,該接口將由幾個具體類實現。 PolygonFactory 將用于從該系列中獲取對象:

      讓我們首先創建 Polygon 接口:

      public interface Polygon { String getType(); }

      接下來,我們將創建一些實現,例如 Square、Triangle 等,它們實現了這個接口并返回一個 Polygon 類型的對象。

      現在我們可以創建一個工廠,將邊數作為參數并返回此接口的適當實現:

      注意客戶端如何依賴這個工廠來給我們一個合適的多邊形,而不必直接初始化對象。

      什么時候使用工廠方法設計模式

      當接口或抽象類的實現預計會頻繁更改時

      當當前的實現不能舒適地適應新的變化時

      當初始化過程比較簡單,構造函數只需要少量參數時

      抽線工廠設計模式

      在上一節中,我們看到了如何使用工廠方法設計模式來創建與單個系列相關的對象。

      相比之下,抽象工廠設計模式用于創建相關或依賴對象的系列。 它有時也被稱為工廠中的工廠。

      《Design Patterns: Elements of Reusable Object-Oriented Software》一書指出,抽象工廠“提供了一個接口,用于創建相關或依賴對象的系列,而無需指定它們的具體類”。 換句話說,這個模型允許我們創建遵循一般模式的對象。

      JDK 中抽象工廠設計模式的一個示例是 javax.xml.parsers.DocumentBuilderFactory 類的 newInstance()。

      在本例中,我們將創建工廠方法設計模式的兩個實現:AnimalFactory 和 ColorFactory。

      之后,我們將使用抽象工廠 AbstractFactory 管理對它們的訪問:

      首先,我們將創建一個 Animal 類家族,稍后將在我們的抽象工廠中使用它。

      這是動物接口:

      public interface Animal { String getAnimal(); String makeSound(); }

      和一個具體的實現 Duck:

      public class Duck implements Animal { @Override public String getAnimal() { return "Duck"; } @Override public String makeSound() { return "Squeks"; } }

      此外,我們可以完全以這種方式創建 Animal 接口(如 Dog、Bear 等)的更具體的實現。

      抽象工廠處理依賴對象的族。 考慮到這一點,我們將引入另外一種顏色系列作為具有一些實現(白色、棕色……)的接口。

      public interface AbstractFactory { T create(String animalType) ; }

      接下來,我們將使用我們在上一節中討論的工廠方法設計模式來實現 AnimalFactory:

      public class AnimalFactory implements AbstractFactory { @Override public Animal create(String animalType) { if ("Dog".equalsIgnoreCase(animalType)) { return new Dog(); } else if ("Duck".equalsIgnoreCase(animalType)) { return new Duck(); } return null; } }

      同樣,我們可以使用相同的設計模式為 Color 接口實現一個工廠。

      設置完所有這些后,我們將創建一個 FactoryProvider 類,該類將為我們提供 AnimalFactory 或 ColorFactory 的實現,具體取決于我們提供給 getFactory() 方法的參數:

      public class FactoryProvider { public static AbstractFactory getFactory(String choice){ if("Animal".equalsIgnoreCase(choice)){ return new AnimalFactory(); } else if("Color".equalsIgnoreCase(choice)){ return new ColorFactory(); } return null; } }

      什么時候抽象工廠設計模式

      客戶端獨立于我們如何在系統中創建和組合對象

      該系統由多個對象族組成,這些族旨在一起使用

      我們需要一個運行時值來構造一個特定的依賴項

      雖然該模式在創建預定義對象時非常有用,但添加新對象可能具有挑戰性。 要支持新類型的對象,需要更改 AbstractFactory 類及其所有子類。

      Builder設計模式

      創建型設計模式簡介

      Builder 設計模式是另一種創建模式,旨在處理相對復雜的對象的構造。

      當創建對象的復雜性增加時,Builder 模式可以通過使用另一個對象(builder)來構造對象,從而分離出實例化過程。

      然后可以使用此構建器通過簡單的逐步方法創建許多其他類似的表示。

      GoF 引入的原始 Builder 設計模式側重于抽象,在處理復雜對象時非常好,但是設計有點復雜。

      Joshua Bloch 在他的《Effective Java》一書中介紹了構建器模式的改進版本,它干凈、可讀性強(因為它使用了流暢的設計)并且從客戶的角度來看易于使用。 在本例中,我們將討論該版本。

      此示例只有一個類 BankAccount,其中包含一個構建器作為靜態內部類:

      public class BankAccount { private String name; private String accountNumber; private String email; private boolean newsletter; // constructors/getters public static class BankAccountBuilder { // builder code } }

      請注意,字段上的所有訪問修飾符都被聲明為私有,因為我們不希望外部對象直接訪問它們。

      構造函數也是私有的,因此只有分配給此類的 Builder 才能訪問它。 構造函數中設置的所有屬性都是從我們作為參數提供的構建器對象中提取的。

      我們在靜態內部類中定義了 BankAccountBuilder:

      public static class BankAccountBuilder { private String name; private String accountNumber; private String email; private boolean newsletter; public BankAccountBuilder(String name, String accountNumber) { this.name = name; this.accountNumber = accountNumber; } public BankAccountBuilder withEmail(String email) { this.email = email; return this; } public BankAccountBuilder wantNewsletter(boolean newsletter) { this.newsletter = newsletter; return this; } public BankAccount build() { return new BankAccount(this); } }

      請注意,我們已經聲明了外部類包含的相同字段集。 任何必填字段都需要作為內部類構造函數的參數,而剩余的可選字段可以使用 setter 方法指定。

      此實現還通過讓 setter 方法返回構建器對象來支持流暢的設計方法。

      最后,build 方法調用外部類的私有構造函數,并將自身作為參數傳遞。 返回的 BankAccount 將使用 BankAccountBuilder 設置的參數進行實例化。

      讓我們看一個構建器模式的快速示例:

      BankAccount newAccount = new BankAccount .BankAccountBuilder("Jon", "22738022275") .withEmail("jon@example.com") .wantNewsletter(true) .build();

      什么時候使用builder設計模式

      當創建對象的過程非常復雜,有很多強制和可選參數時

      當構造函數參數數量增加導致構造函數列表很大時

      當客戶端期望構造的對象有不同的表示時

      結論

      在本文中,我們了解了 Java 中的創建設計模式。 我們還討論了它們的四種不同類型,即 Singleton、Factory Method、Abstract Factory 和 Builder Pattern,它們的優點、示例以及我們應該何時使用它們。

      Java

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:excel表格中制作比賽排序自動評分表的方法是什么
      下一篇:Python學習之面向對象(封裝、繼承、多態)
      相關文章
      亚洲伦理一区二区| 亚洲精品福利网泷泽萝拉| 亚洲日本久久久午夜精品| 亚洲国产精品成人综合色在线婷婷| 亚洲AV综合色区无码另类小说| 亚洲日韩精品一区二区三区无码| 狠狠亚洲狠狠欧洲2019| 久久久久亚洲精品天堂久久久久久| 亚洲国产精品一区二区九九| 国产成人亚洲精品蜜芽影院| 韩国亚洲伊人久久综合影院| 亚洲AV无码国产剧情| 国产偷国产偷亚洲清高APP| 鲁死你资源站亚洲av| 亚洲AV成人无码网天堂| 亚洲AV第一成肉网| 午夜亚洲av永久无码精品| 亚洲国产精品不卡毛片a在线| 爱爱帝国亚洲一区二区三区| 亚洲国产成人AV网站| 亚洲国产成人AV网站| 亚洲国产午夜福利在线播放| 午夜亚洲乱码伦小说区69堂| 亚洲精品无码99在线观看| 久久青青草原亚洲av无码| 亚洲人成网77777亚洲色| 亚洲成a人片在线观看无码 | 亚洲国产精品无码专区在线观看 | 亚洲中文字幕无码亚洲成A人片| 亚洲熟女www一区二区三区| 亚洲AV无码一区二区三区久久精品| 337p日本欧洲亚洲大胆人人| 亚洲精品国产自在久久| 亚洲宅男天堂在线观看无病毒| 亚洲国产精品无码成人片久久| 亚洲午夜精品一区二区| 亚洲中文无码a∨在线观看| 亚洲国产精品99久久久久久| 亚洲成aⅴ人片久青草影院| 国产国拍精品亚洲AV片| 亚洲国产精品自在在线观看|