工廠方法模式

2018年8月22日19:34:48html

工廠方法模式

定義

吾欲娶卿,必問卿之父母,謂之父母之命。java

工廠方法模式(Factory Method),定義一個用於建立對象的接口,讓子類決定實例化哪個類。工廠方法使一個類的實例化延遲到其子類。 ——《設計模式:可複用面向對象軟件的基礎》git

使用場景

工廠方法模式在簡單工廠模式的基礎上,將判斷邏輯的選擇權上交給客戶端,讓客戶端決定使用哪一個具體工廠類。這算是工廠方法相比與簡單工廠模式的缺點吧,這樣的話,你就要事先知道有什麼具體工廠類。相對於直白的new對象,不須要記住具體產品類,服務端隱藏了具體產品類的建立細節,在具體工廠類中不必定就是建立具體產品類,也能夠作一些其餘事情,符合面向對象的封裝性。github

簡單工廠模式加產品,須要修改內部判斷邏輯,這是違反設計模式六大模式中的開閉原則(挖坑),就是對擴展是開放的,對修改是關閉的。工廠方法模式加產品,只需增長相對應的具體工廠對象便可,符合開閉原則,這是工廠方法模式優勢之一。我的觀點:工廠方法模式適合那種常常更替(即增長和刪除)具體產品對象的場景,正好利用了這個優勢。如服裝換季,你是一個設計師,換季了新的產品上架,加上新產品,老闆選擇新工廠,銷售商家只須要從工廠獲取新產品便可,舊產品下架,和舊工廠合同到期,就這樣。設計模式

角色

將簡單工廠模式的工廠角色內部邏輯判斷上交給客戶端後,分別封裝建立對象細節到具體工廠類,具體工廠類都繼承於一個共同的接口。簡單工廠模式可查看:簡單工廠模式ide

工廠方法模式有如下四種角色:測試

  • 抽象工廠角色(IFactory):具體工廠公共接口,定義工廠方法返回產品
  • 具體工廠角色(ConcreteFactoryImpl):繼承工廠工廠公共接口,實現工廠方法,運行期返回具體產品實例
  • 抽象產品角色(IProduct)
  • 具體產品角色(ConcreteProductImpl)

圖示

工廠方法模式結構圖

代碼示例

代碼示例依然用的是加減乘除運算操做,跟簡單工廠模式同樣,只是將工廠類SimpleFactory拆分爲抽象工廠類和具體工廠類。簡單工廠模式可查看:簡單工廠模式設計

類依賴關係圖:
工廠方法模式類依賴關係圖3d

抽象工廠角色(IOperationFactory.java):code

public interface IOperationFactory {
    public IOperation createOperation();
}

抽象出來的具體工廠對象公共接口。

具體工廠角色(AddOperationFactoryImpl.java、SubOperationFactoryImpl.java、MulOperationFactoryImpl.java、DivOperationFactoryImpl.java):

// 加法工廠
public class AddOperationFactoryImpl implements IOperationFactory {

    @Override
    public IOperation createOperation() {
        return new AddOperationImpl();
    }

}
// 減法工廠
public class SubOperationFactoryImpl implements IOperationFactory {

    @Override
    public IOperation createOperation() {
        return new SubOperationImpl();
    }

}
//  乘法工廠
public class MulOperationFactoryImpl implements IOperationFactory {

    @Override
    public IOperation createOperation() {
        return new MulOperationImpl();
    }

}
//  除法工廠
public class DivOperationFactoryImpl implements IOperationFactory {

    @Override
    public IOperation createOperation() {
        return new DivOperationImpl();
    }

}

每一個具體工廠對象對應一個具體產品對象。

抽象產品角色(IProduct.java):

public interface IOperation {
    public int getResult(int a, int b);
}

具體產品角色(AddOperationImpl.java、SubOperationImpl.java、MulOperationImpl.java、DivOperationImpl.java):

// 加法實現類
public class AddOperationImpl implements IOperation{

    @Override
    public int getResult(int a, int b) {
        return a + b;
    }

}
// 減法實現類
public class SubOperationImpl implements IOperation {
    
    @Override
    public int getResult(int a, int b) {
        return a - b;
    }
}
// 乘法實現類
public class MulOperationImpl implements IOperation {

    @Override
    public int getResult(int a, int b) {
        return a * b;
    }

}
// 除法實現類
public class DivOperationImpl implements IOperation {

    @Override
    public int getResult(int a, int b) {
        return a / b;
    }

}

測試類(FactoryMethodTest.java):

public class FactoryMethodTest {
    
    public static void main(String[] args) {
        int a = 999, b = 888;
        // 加
        // 建立具體工廠
        IOperationFactory operationFactory = new AddOperationFactoryImpl();
        // 建立具體產品
        IOperation operation = operationFactory.createOperation();
        // 調用具體產品的功能
        int result = operation.getResult(a, b); // 1887
        System.out.println(result);
        
        // 減
        operationFactory = new SubOperationFactoryImpl();
        operation = operationFactory.createOperation();
        result = operation.getResult(a, b); // 111
        System.out.println(result);
        
        // 乘
        operationFactory = new MulOperationFactoryImpl();
        operation = operationFactory.createOperation();
        result = operation.getResult(a, b); // 887112
        System.out.println(result);
        
        // 除
        operationFactory = new DivOperationFactoryImpl();
        operation = operationFactory.createOperation();
        result = operation.getResult(a, b); // 1
        System.out.println(result);
        
    }
    
}

客戶端要判斷使用什麼具體工廠對象,從而實例化所需的具體產品對象。

優勢(小抄)

(連接在文末參考處)

一、在工廠方法模式中,工廠方法用來建立客戶所須要的產品,同時還向客戶隱藏了哪一種具體產品類將被實例化這一細節,用戶只須要關心所需產品對應的工廠,無須關心建立細節,甚至無須知道具體產品類的類名。

二、基於工廠角色和產品角色的多態性設計是工廠方法模式的關鍵。它可以使工廠能夠自主肯定建立何種產品對象,而如何建立這個對象的細節則徹底封裝在具體工廠內部。工廠方法模式之因此又被稱爲多態工廠模式,是由於全部的具體工廠類都具備同一抽象父類。

三、使用工廠方法模式的另外一個優勢是在系統中加入新產品時,無須修改抽象工廠和抽象產品提供的接口,無須修改客戶端,也無須修改其餘的具體工廠和具體產品,而只要添加一個具體工廠和具體產品就能夠了。這樣,系統的可擴展性也就變得很是好,徹底符合「開閉原則」。

缺點(小抄)

一、在添加新產品時,須要編寫新的具體產品類,並且還要提供與之對應的具體工廠類,系統中類的個數將成對增長,在必定程度上增長了系統的複雜度,有更多的類須要編譯和運行,會給系統帶來一些額外的開銷。

二、因爲考慮到系統的可擴展性,須要引入抽象層,在客戶端代碼中均使用抽象層進行定義,增長了系統的抽象性和理解難度,且在實現時可能須要用到DOM、反射等技術,增長了系統的實現難度。

總結

工廠方法模式是簡單工廠模式的進一步抽象和推廣。

因爲使用了面向對象的多態性,工廠方法模式保持了簡單工廠模式的優勢,並且克服了它的缺點。

全部代碼可見於Github.Mingmingcome

參考:

工廠方法模式(Factory Method Pattern)

相關文章
相關標籤/搜索