Kotlin基礎知識的學習,請參考以前的文章:html
Kotlin入門第三課:數據類型post
學習一門語言,沒有必要掌握所有特性纔去實踐。入門以後能夠開始閱讀好的開源項目代碼,本身動手實現一些簡單的案例,有困難再去補充學習相關的知識點,這樣反覆的過程效果會比較好。測試
最近在從新學習設計模式,正好用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. 適用場景
工廠類負責建立的對象比較少:因爲建立的對象較少,不會形成工廠方法中的業務邏輯太過複雜;
客戶端只知道傳入工廠類的參數,對於如何建立對象不關心:客戶端既不須要關心建立細節,甚至連類名都不須要記住,只須要知道類型所對應的參數。