簡單工廠模式(Java與Kotlin版)

 

Kotlin基礎知識的學習,請參考以前的文章:html

Kotlin入門第一課:從對比Java開始設計模式

Kotlin入門第二課:集合操做ide

Kotlin入門第三課:數據類型post

初次嘗試用Kotlin實現Android項目學習

 

學習一門語言,沒有必要掌握所有特性纔去實踐。入門以後能夠開始閱讀好的開源項目代碼,本身動手實現一些簡單的案例,有困難再去補充學習相關的知識點,這樣反覆的過程效果會比較好。測試

 

最近在從新學習設計模式,正好用Kotlin來實現對應的示例代碼。本文就從簡單工廠模式開始。spa

 

說明:設計模式的文字性解釋參考或引用了這篇文章,做者的設計模式系列文章寫得挺不錯,感興趣的朋友能夠移步去閱讀。因爲做者沒有給出具體的示例代碼,因此本人打算在學習的同時,利用Java和Kotlin將各個模式實現一遍(雖然網上有現成代碼),寫出總結。目的是學習設計模式和Kotlin語言,分享過程當中的點滴。設計

 

1. 定義code

簡單工廠模式(Simple Factory Pattern):又稱爲靜態工廠方法(Static Factory Method)模式,它屬於類建立型模式。在簡單工廠模式中,能夠根據參數的不一樣返回不一樣類的實例。簡單工廠模式專門定義一個類來負責建立其餘類的實例,被建立的實例一般都具備共同的父類。htm

 

2. 結構

Factory:工廠角色,負責實現建立全部實例的內部邏輯;

Product:抽象產品角色,是所建立的全部對象的父類,負責描述全部實例所共有的公共接口;

ConcreteProduct:具體產品角色,是建立目標,全部建立的對象都充當這個角色的某個具體類的實例。

 

3. 代碼

3.1 Java

Product:

1 abstract class Product {
2     abstract void print();
3 }

定義了抽象產品角色,及抽象方法print。

ConcreteProductA與ConcreteProductB:

 1 class ConcreteProductA extends Product {
 2     void print() {
 3         System.out.println("print of ConcreteProductA");
 4     }
 5 }
 6 
 7 class ConcreteProductB extends Product {
 8     void print() {
 9         System.out.println("print of ConcreteProductB");
10     }
11 }

定義了兩個具體產品角色,分別實現了print方法。

Factory:

 1 class Factory {
 2     Product createProduct(String tag) {
 3         Product product = null;
 4         switch (tag) {
 5             case "A":
 6                 product = new ConcreteProductA();
 7                 System.out.println("create ProductA");
 8                 break;
 9             case "B":
10                 product = new ConcreteProductB();
11                 System.out.println("create ProductB");
12                 break;
13             default:
14                 break;
15         }
16 
17         return product;
18     }
19 }

工廠角色,實現了根據傳入的參數來建立產品的功能。注意,新版的Java才能將String類型做爲switch參數。

SimpleFactoryPattern:

 1 public class SimpleFactoryPattern {
 2     public static void main(String[] args) {
 3         System.out.println("Simple Factory Pattern");
 4 
 5         Factory factory = new Factory();
 6         Product product = factory.createProduct("A");
 7         if (product != null) {
 8             product.print();
 9         }
10         product = factory.createProduct("B");
11         if (product != null) {
12             product.print();
13         }
14         product = factory.createProduct("C");
15         if (product != null) {
16             product.print();
17         }
18     }
19 }

測試用例,代碼中加入了產品對象是否爲null的判斷,由於當用戶傳入錯誤的參數時是不能獲得想要的產品的。

輸出:

 

3.2 Kotlin

因爲Kotlin和Java的實現只是代碼上的不一樣,因此下面只會說明存在差別的地方。之後要想由Kotlin轉向Java,得先從細節上慢慢積累。雖然大多知識點在前面幾篇文章有講到,但仍是會提一下,溫故而知新。

Product:

1 abstract class Product {
2     abstract fun print()
3 }

方法定義添加fun關鍵字;語句結尾沒有分號。

ConcreteProductA與ConcreteProductB:

 1 class ConcreteProductA: Product() {
 2     override fun print() {
 3         println("print of ConcreteProductA")
 4     }
 5 }
 6 
 7 class ConcreteProductB: Product() {
 8     override fun print() {
 9         println("print of ConcreteProductB")
10     }
11 }

類繼承用冒號代替extends關鍵字,基類名後添加括號;方法覆寫添加override關鍵字;輸出方法相似Python,沒有System.out等繁瑣的前綴。

Factory:

 1 class Factory {
 2     fun createProduct(tag: String): Product? {
 3         var product: Product? = null
 4         when (tag) {
 5             "A" -> {
 6                 product = ConcreteProductA()
 7                 println("create ProductA")
 8             }
 9             "B" -> {
10                 product = ConcreteProductB()
11                 println("create ProductB")
12             }
13             else -> {
14             }
15         }
16 
17         return product
18     }
19 }

方法參數是變量在前,類型在後,用冒號隔離;方法返回類型寫在方法名定義後,用冒號分離;沒有返回值則可不寫類型,或者寫Unit;不肯定對象是否爲空,聲明時須加上問號;用when代替if或者switch結構更簡潔易用。

SimpleFactoryPattern:

 1 fun main(args: Array<String>) {
 2     println("Simple Factory Pattern")
 3 
 4     val factory = Factory()
 5     var product: Product? = factory.createProduct("A")
 6     if (product != null) {
 7         product.print()
 8     }
 9     product = factory.createProduct("B")
10     if (product != null) {
11         product.print()
12     }
13     product = factory.createProduct("C")
14     if (product != null) {
15         product.print()
16     }
17 }

主方法不須要在外面套一個public類;對象建立不用加new關鍵字。

輸出同上。

 

4. 優缺點

4.1 優勢

工廠類含有必要的判斷邏輯,能夠決定在何時建立哪個產品類的實例,客戶端能夠免除直接建立產品對象的責任,而僅僅「消費」產品;簡單工廠模式經過這種作法實現了對責任的分割,它提供了專門的工廠類用於建立對象;

客戶端無須知道所建立的具體產品類的類名,只須要知道具體產品類所對應的參數便可,對於一些複雜的類名,經過簡單工廠模式能夠減小使用者的記憶量;

經過引入配置文件,能夠在不修改任何客戶端代碼的狀況下更換或增長新的具體產品類,在必定程度上提升了系統的靈活性。

 

4.2 缺點

因爲工廠類集中了全部產品建立邏輯,一旦不能正常工做,整個系統都要受到影響;

使用簡單工廠模式將會增長系統中類的個數,在必定程序上增長了系統的複雜度和理解難度;

系統擴展困難,一旦添加新產品就不得不修改工廠邏輯,在產品類型較多時,有可能形成工廠邏輯過於複雜,不利於系統的擴展和維護;

簡單工廠模式因爲使用了靜態工廠方法,形成工廠角色沒法造成基於繼承的等級結構。

 

5. 適用場景

工廠類負責建立的對象比較少:因爲建立的對象較少,不會形成工廠方法中的業務邏輯太過複雜;

客戶端只知道傳入工廠類的參數,對於如何建立對象不關心:客戶端既不須要關心建立細節,甚至連類名都不須要記住,只須要知道類型所對應的參數。

相關文章
相關標籤/搜索