工廠方法模式(Java與Kotlin版)
前文推送
設計模式
簡單工廠模式(Java與Kotlin版)
Kotlin基礎知識
Kotlin入門第一課:從對比Java開始
Kotlin入門第二課:集合操作
Kotlin入門第三課:數據類型
初次嘗試用Kotlin實現Android項目
1. 定義
工廠方法模式(Factory Method Pattern)又稱為工廠模式,也叫虛擬構造器(Virtual Constructor)模式或者多態工廠(Polymorphic Factory)模式,它屬於類創建型模式。在工廠方法模式中,工廠父類負責定義創建產品對象的公共接口,而工廠子類則負責生成具體的產品對象,這樣做的目的是將產品類的實例化操作延遲到工廠子類中完成,即通過工廠子類來確定究竟應該實例化哪一個具體產品類。
2. 結構
Factory:抽象工廠角色,定義創建實例的抽象方法;
ConcreteFactory:具體工廠角色,負責創建特定實例;
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 abstract class Factory { 2 abstract Product factoryMethod(); 3 }
定義了抽象工廠角色,及抽象方法factoryMethod。
ConcreteFactoryA與ConcreteFactoryB:
1 class ConcreteFactoryA extends Factory { 2 Product factoryMethod() { 3 System.out.println("create ProductA"); 4 5 return new ConcreteProductA(); 6 } 7 } 8 9 class ConcreteFactoryB extends Factory { 10 Product factoryMethod() { 11 System.out.println("create ProductB"); 12 13 return new ConcreteProductB(); 14 } 15 }
定義了兩個具體工廠角色,分別實現了factoryMethod方法。
FactoryMethodPattern:
1 public class FactoryMethodPattern { 2 public static void main(String[] args) { 3 System.out.println("Factory Method Pattern"); 4 5 Factory factory = new ConcreteFactoryA(); 6 Product product = factory.factoryMethod(); 7 product.print(); 8 9 factory = new ConcreteFactoryB(); 10 product = factory.factoryMethod(); 11 product.print(); 12 } 13 }
不同的具體產品實例,用不同的具體工廠來創建。
輸出:
3.2 Kotlin
Product:
1 abstract class Product {
2 abstract fun print()
3 }
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 }
Factory:
1 abstract class Factory { 2 abstract fun factoryMethod(): Product 3 }
ConcreteFactoryA與ConcreteFactoryB:
1 class ConcreteFactoryA : Factory() { 2 override fun factoryMethod(): Product { 3 println("create ProductA") 4 5 return ConcreteProductA() 6 } 7 } 8 9 class ConcreteFactoryB : Factory() { 10 override fun factoryMethod(): Product { 11 println("create ProductB") 12 13 return ConcreteProductB() 14 } 15 }
FactoryMethodPattern:
1 fun main(args: Array<String>) { 2 println("Factory Method Pattern") 3 4 var factory: Factory = ConcreteFactoryA() 5 var product = factory.factoryMethod() 6 product.print() 7 8 factory = ConcreteFactoryB() 9 product = factory.factoryMethod() 10 product.print() 11 }
輸出同上。
4. 優缺點
4.1 優點
在工廠方法模式中,工廠方法用來創建客戶所需要的產品,同時還向客戶隱藏了哪種具體產品類將被實例化這一細節,用戶只需要關心所需產品對應的工廠,無須關心創建細節,甚至無須知道具體產品類的類名;
基於工廠角色和產品角色的多態性設計是工廠方法模式的關鍵。它能夠使工廠可以自主確定創建何種產品對象,而如何創建這個對象的細節則完全封裝在具體工廠內部。工廠方法模式之所以又被稱為多態工廠模式,是因為所有的具體工廠類都具有同一抽象父類;
使用工廠方法模式的另一個優點是在系統中加入新產品時,無須修改抽象工廠和抽象產品提供的接口,無須修改客戶端,也無須修改其他的具體工廠和具體產品,而只要添加一個具體工廠和具體產品就可以了。這樣,系統的可擴展性也就變得非常好,完全符合“開閉原則”。
4.2 缺點
在添加新產品時,需要編寫新的具體產品類,而且還要提供與之對應的具體工廠類,系統中類的個數將成對增加,在一定程度上增加了系統的復雜度,有更多的類需要編譯和運行,會給系統帶來一些額外的開銷;
由於考慮到系統的可擴展性,需要引入抽象層,在客戶端代碼中均使用抽象層進行定義,增加了系統的抽象性和理解難度,且在實現時可能需要用到DOM、反射等技術,增加了系統的實現難度。
5. 適用場景
一個類不知道它所需要的對象的類:在工廠方法模式中,客戶端不需要知道具體產品類的類名,只需要知道所對應的工廠即可,具體的產品對象由具體工廠類創建;客戶端需要知道創建具體產品的工廠類;
一個類通過其子類來指定創建哪個對象:在工廠方法模式中,對於抽象工廠類只需要提供一個創建產品的接口,而由其子類來確定具體要創建的對象,利用面向對象的多態性和裏氏代換原則,在程序運行時,子類對象將覆蓋父類對象,從而使得系統更容易擴展;
將創建對象的任務委托給多個工廠子類中的某一個,客戶端在使用時可以無須關心是哪一個工廠子類創建產品子類,需要時再動態指定,可將具體工廠類的類名存儲在配置文件或數據庫中。
工廠方法模式(Java與Kotlin版)