目錄
概念
工廠方法模式,又稱工廠模式、多態工廠模式和虛擬構造器模式,通過定義工廠父類負責定義創建對象的公共接口,而子類則負責生成具體的對象。
實現原理
工廠方法模式對簡單工廠模式進行了抽象。有一個抽象的Factory類(可以是抽象類和接口),這個類將不再負責具體的產品生產,而是隻制定一些規範,具體的生產工作由其子類去完成。在這個模式中,工廠類和產品類往往可以依次對應。即一個抽象工廠對應一個抽象產品,一個具體工廠對應一個具體產品,這個具體的工廠就負責生產對應的產品。
解決的問題
工廠方法模式是簡單工廠模式的衍生或者說改進,解決了簡單工廠模式存在的問題,友好地遵循了開閉原則,實現了可擴展。其次更復雜的層次結構,可以應用於產品結果複雜的場合。
作用和意義
工廠方法模式的意義是定義一個創建產品對象的工廠接口,將實際創建工作推遲到子類當中。核心工廠類不再負責產品的創建,這樣核心類成爲一個抽象工廠角色,僅負責具體工廠子類必須實現的接口,這樣進一步抽象化的好處是使得工廠方法模式可以使系統在不修改具體工廠角色的情況下引進新的產品。
角色構成
工廠方法模式是一種常用的類創建型設計模式,此模式的核心精神是封裝類中變化的部分,提取其中個性化善變的部分爲獨立類,通過依賴注入以達到解耦、複用和方便後期維護拓展的目的。它的核心結構有四個角色,分別是抽象工廠;具體工廠;抽象產品;具體產品。
抽象工廠(Creator)角色
是工廠方法模式的核心,與應用程序無關。任何在模式中創建的對象的工廠類必須實現這個接口。
具體工廠(Concrete Creator)角色
這是實現抽象工廠接口的具體工廠類,包含與應用程序密切相關的邏輯,並且受到應用程序調用以創建產品對象。
抽象產品(Product)角色
工廠方法模式所創建的對象的超類型,也就是產品對象的共同父類或共同擁有的接口
具體產品(Concrete Product)角色
這個角色實現了抽象產品角色所定義的接口。某具體產品有專門的具體工廠創建,它們之間往往一一對應。
UML類圖
代碼實現
抽象工廠
IPressFactory.java
package pattern.factory.factorymethod.factorymethod1.factoryinterface;
import pattern.factory.factorymethod.factorymethod1.productinterface.IBook;
/**
* 〈一句話功能簡述〉抽象工廠角色<br>
* 〈功能詳細描述〉給具體工廠實現用的
*
* @author 劉斌
* @date 2020/3/1
* @see [相關類/方法](可選)
* @since [產品/模塊版本] (可選)
*/
public interface IPressFactory {
/**
* 獲取書籍信息
*
* @return 書籍
*/
IBook getBookInfo();
}
具體工廠
HarvardPressFactory.java
package pattern.factory.factorymethod.factorymethod1.factoryimpl;
import pattern.factory.factorymethod.factorymethod1.factoryinterface.IPressFactory;
import pattern.factory.factorymethod.factorymethod1.productimpl.HongLouBook;
import pattern.factory.factorymethod.factorymethod1.productinterface.IBook;
/**
* 〈一句話功能簡述〉哈佛大學出版社(相當於一個工廠,出版社是發行和生產書的工廠)<br>
* 〈功能詳細描述〉具體工廠角色
*
* @author 劉斌
* @date 2020/3/1
* @see [相關類/方法](可選)
* @since [產品/模塊版本] (可選)
*/
public class HarvardPressFactory implements IPressFactory {
@Override
public IBook getBookInfo() {
return new HongLouBook();
}
}
OxfordPressFactory.java
package pattern.factory.factorymethod.factorymethod1.factoryimpl;
import pattern.factory.factorymethod.factorymethod1.factoryinterface.IPressFactory;
import pattern.factory.factorymethod.factorymethod1.productimpl.SanGuoBook;
import pattern.factory.factorymethod.factorymethod1.productinterface.IBook;
/**
* 〈一句話功能簡述〉牛津大學出版社(相當於一個工廠,出版社是發行和生產書的工廠)<br>
* 〈功能詳細描述〉具體工廠角色
*
* @author 劉斌
* @date 2020/3/1
* @see [相關類/方法](可選)
* @since [產品/模塊版本] (可選)
*/
public class OxfordPressFactory implements IPressFactory {
@Override
public IBook getBookInfo() {
return new SanGuoBook();
}
}
抽象產品
IBook.java
package pattern.factory.factorymethod.factorymethod1.productinterface;
/**
* 〈一句話功能簡述〉抽象產品角色<br>
* 〈功能詳細描述〉給具體產品實現用的
*
* @author 劉斌
* @date 2020/3/1
* @see [相關類/方法](可選)
* @since [產品/模塊版本] (可選)
*/
public interface IBook {
/**
* 名稱
* @return 書名
*/
String name();
/**
* 地址
* @return 書價格
*/
double price();
}
具體產品
HongLouBook.java
package pattern.factory.factorymethod.factorymethod1.productimpl;
import pattern.factory.factorymethod.factorymethod1.productinterface.IBook;
/**
* 〈一句話功能簡述〉紅樓夢(具體的一本書,相當於具體的一個產品)<br>
* 〈功能詳細描述〉具體產品角色
*
* @author 劉斌
* @date 2020/3/1
* @see [相關類/方法](可選)
* @since [產品/模塊版本] (可選)
*/
public class HongLouBook implements IBook {
@Override
public String name() {
return "書名:紅樓夢";
}
@Override
public double price() {
return 30;
}
}
SanGuoBook.java
package pattern.factory.factorymethod.factorymethod1.productimpl;
import pattern.factory.factorymethod.factorymethod1.productinterface.IBook;
/**
* 〈一句話功能簡述〉三國演義(具體的一本書,相當於具體的一個產品)<br>
* 〈功能詳細描述〉具體產品角色
*
* @author 劉斌
* @date 2020/3/1
* @see [相關類/方法](可選)
* @since [產品/模塊版本] (可選)
*/
public class SanGuoBook implements IBook {
@Override
public String name() {
return "三國演義";
}
@Override
public double price() {
return 40;
}
}
客戶端調用
FactoryMethodFirstDemo.java
package pattern.factory.factorymethod.factorymethod1;
import pattern.factory.factorymethod.factorymethod1.factoryimpl.HarvardPressFactory;
import pattern.factory.factorymethod.factorymethod1.factoryimpl.OxfordPressFactory;
import pattern.factory.factorymethod.factorymethod1.factoryinterface.IPressFactory;
import pattern.factory.factorymethod.factorymethod1.productinterface.IBook;
/**
* 〈一句話功能簡述〉工廠方法模式:客戶端調用<br>
* 〈功能詳細描述〉
*
* @author 劉斌
* @date 2020/3/1
* @see [相關類/方法](可選)
* @since [產品/模塊版本] (可選)
*/
public class FactoryMethodFirstDemo {
public static void main(String[] args) {
IPressFactory harvardPressFactory = new HarvardPressFactory();
IBook book1 = harvardPressFactory.getBookInfo();
System.out.println(book1.name() + ", 價格:" + book1.price());
System.out.println("=============================");
IPressFactory oxfordPressFactory = new OxfordPressFactory();
IBook book2 = oxfordPressFactory.getBookInfo();
System.out.println(book2.name() + ", 價格:" + book2.price());
}
}
工廠方法模式-控制檯輸出