02-簡單工廠&工廠方法&抽象工廠

1、簡單工廠(Simple Factory)

概述:

在創建一個對象時不向客戶暴露內部細節,並提供一個創建對象的通用接口。

錯誤的方式:





 

正確的方式:


 

 

簡單工廠把實例化的操作單獨放到一個類中,這個類就成爲簡單工廠類,讓簡單工廠類來決定應該用哪個具體子類來實例化。

這樣做能把客戶類和具體子類的實現解耦,客戶類不再需要知道有哪些子類以及應當實例化哪個子類。客戶類往往有多個,如果不使用簡單工廠,那麼所有的客戶類都要知道所有子類的細節。而且一旦子類發生改變,例如增加子類,那麼所有的客戶類都要進行修改。

注:並不是GOF23種設計模式

In JDK:

Calendar

-createCalendar()

 

2、工廠方法(Factory Method

概述:

定義了一個創建對象的接口,但由子類決定要實例化哪個類。工廠方法把實例化操作推遲到子類。

public abstract class Factory {

    abstract public Product factoryMethod();

    public void doSomething() {

    Product product = factoryMethod();

    // do something with the product

    }

}

public class ConcreteFactory extends Factory {

    public Product factoryMethod() {

        return new ConcreteProduct();

    }

}

public class ConcreteFactory1 extends Factory {

    public Product factoryMethod() {

        return new ConcreteProduct1();

    }

}

public class ConcreteFactory2 extends Factory {

    public Product factoryMethod() {

        return new ConcreteProduct2();

    }

}

在簡單工廠中,創建對象的是另一個類,而在工廠方法中,是由子類來創建對象。

上圖中,Factory 有一個 doSomething() 方法,這個方法需要用到一個產品對象,這個產品對象由 factoryMethod() 方法創建。該方法是抽象的,需要由子類去實現。

使用場景:

創建對象需要大量重複的代碼

客戶端( 應用層)不需要依賴產品類實例如何創建、實現等細節

一個類通過其子類來指定創建哪個對象

優點:

用戶只需要關心所需產品對應的工廠,無須關心創建細節 加入新產品符合開閉原則,提高可擴展性

缺點:

類的個數容易過多,增加複雜度 增加了系統的抽象性和理解難度

 

In JDK

Collection 

~iterator()

ArrayList

+iterator()

3、抽象工廠(Abstract Factory)

概述:

適用場景:

客戶端(應用層)不依賴於產品類實例如何被創建、實現等細節

強調一系列相關的產品對象(屬於同一產品族)一起使用創建對象需要大量重複的代碼

提供一個產品類的庫,所有的產品以同樣的接口出現,從而使客戶端不依賴於具體實現

優點:

具體產品在應用層代碼隔離,無須關心創建細節,將一個系列的產品族統一到一起創建

缺點:

規定了所有可能被創建的產品集合,產品族中擴展新的產品困難,需要修改抽象工廠的接口

增加了系統的抽象性和理解難度

關於抽象工廠的產品族:

提供一個接口,用於創建相關的對象家族 

UML&實例DEMO

源碼鏈接:https://github.com/NoSuchClass/design_pattern/tree/master/src/creational/abstractfactory

 

抽象工廠模式創建的是產品族,也就是很多對象而不是一個對象,並且這些對象是相關的,也就是說必須一起創建出來。而工廠方法模式只是用於創建一個對象,這和抽象工廠模式有很大不同。

抽象工廠模式用到了工廠方法模式來創建單一對象,AbstractFactory 中的 createProductA() 和 createProductB() 方法都是讓子類來實現,這兩個方法單獨來看就是在創建一個對象,這符合工廠方法模式的定義。

至於創建對象的家族這一概念是在 Client 體現,Client 要通過 AbstractFactory 同時調用兩個方法來創建出兩個對象,在這裏這兩個對象就有很大的相關性,Client 需要同時創建出這兩個對象。

從高層次來看,抽象工廠使用了組合,即 Cilent 組合了 AbstractFactory,而工廠方法模式使用了繼承。

 

In JDK

java.sql.Connection:

這就是一個抽象工廠,裏面都是一個產品族的獲取

java.sql.Statement

In MyBatis

java.sql.SqlSessionFactory:

這兒不但獲取了SqlSession,還獲取了Configuration,是同一產品族

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章