1. 程式人生 > >工廠方法模式(Java與Kotlin版)

工廠方法模式(Java與Kotlin版)

http www pattern static 難度 microsoft 運行時 sta 父類

前文推送

設計模式

簡單工廠模式(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版)