Java設計模式:Factory Method(工廠方法)模式

概念定義

工廠方法(Factory Method)模式,又稱多態工廠(Polymorphic Factory)模式或虛擬構造器(Virtual Constructor)模式。工廠方法模式經過定義工廠抽象父類(或接口)負責定義建立對象的公共接口,而工廠子類(或實現類)則負責生成具體的對象。java

工廠方法模式對簡單工廠模式中的工廠類進一步抽象。核心工廠類再也不負責產品的建立,而是演變爲一個抽象工廠角色,僅負責定義具體工廠子類必須實現的接口。同時,針對不一樣的產品提供不一樣的工廠。即每一個產品都有一個與之對應的工廠。這樣,系統在增長新產品時就不會修改工廠類邏輯而是添加新的工廠子類,從而彌補簡單工廠模式對修改開放的缺陷。spring

在實際項目中,工廠方法模式是使用較多的工廠模式。數據庫

應用場景

  • 當一個類不知道它所須要的對象的類時
    在工廠方法模式中,客戶端不須要知道具體產品類的類名,只須要知道所對應的工廠便可,具體的產品對象由具體工廠類建立。
  • 當一個類但願經過其子類來指定建立哪一個對象時
    在工廠方法模式中,抽象工廠類只需提供一個建立產品的接口,而由其子類來肯定具體要建立的對象。利用面向對象的多態性和里氏替換原則,程序運行時子類對象將覆蓋父類對象,從而使得系統更容易擴展。
  • 將建立對象的任務委託給多個工廠子類中的某一個,客戶端在使用時能夠無需關心是哪一個工廠子類建立產品子類,須要時再動態指定,可將具體工廠類的類名存儲在配置文件或數據庫中。

示例代碼

工廠方法模式由工廠接口(或抽象類)、一組實現工廠接口工廠類、一個產品接口(或抽象類)和一組實現產品接口的具體產品組成。某具體產品由其對應的具體工廠類建立。api

本節經過一個"喜聞樂見"的豪車系列,展現簡單工廠模式的實現。示例代碼以下:框架

// 產品接口 //
public interface ICar { // 也可定義爲抽象類,但接口擴展性更好
    void drive();
}
// 若干具體的產品 //
public class Bmw implements ICar {
    @Override
    public void drive() { System.out.println("drive a Bmw"); }
}
public class Benz implements ICar {
    @Override
    public void drive() { System.out.println("drive a Benz"); }
}
public class Audi implements ICar {
    @Override
    public void drive() { System.out.println("drive a Audi"); }
}
// 工廠接口 //
public interface IFactory { // 也可定義爲抽象類,但接口擴展性更好
    public ICar create();
}
// 若干具體的工廠,與具體產品一一對應 //
public class BmwFactory implements IFactory {
    @Override
    public ICar create() { return new Bmw(); }
}
public class BenzFactory implements IFactory {
    @Override
    public ICar create() { return new Benz(); }
}
public class AudiFactory implements IFactory {
    @Override
    public ICar create() { return new Audi(); }
}

客戶端經過new BenzFactory().create().drive()便可建立Benz實例並調用其drive()方法。新增豪車時,只須要新增豪車自身產品類和對應的工廠類,而不須要修改任何已有類。ide

開源框架中,經常經過配置文件制定具體的工廠類,其模式形如:code

public <T> T getProduct(typeOrName) {
    IProductFactory iProductFactory = getIProductFactory(); // 經過配置文件獲取具體工廠類
    return iProductFactory.getProduct(typeOrName);
}

模式優缺點

工廠方法模式的優勢以下:對象

  • 客戶端只依賴產品的抽象,符合依賴倒置原則;無需關注具體產品,符合迪米特(最少知識)原則。
  • 工廠方法模式符合開放封閉原則,新增產品時只需增長相應的產品和工廠類,而無需修改現有代碼。
  • 工廠方法模式符合單一職責原則,每一個具體的工廠類只負責建立對應的產品。
  • 工廠方法模式不使用靜態工廠方法,能夠造成基於繼承的等級結構。

缺點以下:繼承

  • 新增產品時除增長新產品類外,還要增長對應的具體工廠類,沒有簡單工廠代碼簡潔、高效。
  • 爲了擴展性而進一步引入抽象層,增長了系統的抽象性和理解難度。

業界實踐

  • org.slf4j.LoggerFactory.getLogger(slf4j-api-1.7.25.jar)
  • org.springframework.context.support.AbstractApplicationContext.getBean(spring-context-4.3.4.RELEASE.jar)
相關文章
相關標籤/搜索