工廠方法模式是類的建立模式,又叫作虛擬構造子(Virtual Constructor)模式或者多態性工廠(Polymorphic Factory)模式。spa
工廠方法模式的用意是定義一個建立產品對象的工廠接口,將實際建立工做推遲到子類中。3d
例如:導出的文件格式也可能有所不一樣,多是HTML、CSV、PDF等。每種格式導出的結構有所不一樣,一種是標準結構,一種是財務須要的結構。對象
抽象工廠(ExportFactory)角色:擔任這個角色的是工廠方法模式的核心,任何在模式中建立對象的工廠類必須實現這個接口。在實際的系統中,這個角色也經常使用抽象類實現。blog
具體工廠(ExportHtmlFactory、ExportPdfFactory)角色:擔任這個角色的是實現了抽象工廠接口的具體JAVA類。具體工廠角色含有與業務密切相關的邏輯,而且受到使用者的調用以建立導出類(如:ExportStandardHtmlFile)。接口
抽象導出(ExportFile)角色:工廠方法模式所建立的對象的超類,也就是全部導出類的共同父類或共同擁有的接口。在實際的系統中,這個角色也經常使用抽象類實現。ci
具體導出(ExportStandardHtmlFile等)角色:這個角色實現了抽象導出(ExportFile)角色所聲明的接口,工廠方法模式所建立的每個對象都是某個具體導出角色的實例。產品
具體代碼實現以下:it
public interface ExportFactory {
public ExportFile factory(String type);
}
public class ExportHtmlFactory implements ExportFactory {
public ExportFile factory(String type) {
if("standard".equals(type)){
return new ExportStandardHtmlFile();
}else if("financial".equals(type)){
return new ExportFinancialHtmlFile();
}else{
throw new RuntimeException("沒有找到對象");
}
}
}
public class ExportPdfFactory implements ExportFactory{
public ExportFile factory(String type) {
if("standard".equals(type)){
return new ExportStandardPdfFile();
}else if("financial".equals(type)){
return new ExportFinancialPdfFile();
}else{
throw new RuntimeException("沒有找到對象");
}
}
}
-----------------------------------------------------------------------------
public interface ExportFile {
public boolean export(String data);
}
public class ExportStandardHtmlFile implements ExportFile {
public boolean export(String data) {
/**
* 業務邏輯
*/
System.out.println("導出標準HTML文件");
return true;
}
}
public class ExportFinancialHtmlFile implements ExportFile {
public boolean export(String data) {
/**
* 業務邏輯
*/
System.out.println("導出財務版HTML文件");
return true;
}
}
public class ExportStandardPdfFile implements ExportFile {
public boolean export(String data) {
/**
* 業務邏輯
*/
System.out.println("導出標準PDF文件");
return true;
}
}
public class ExportFinancialPdfFile implements ExportFile {
public boolean export(String data) {
/**
* 業務邏輯
*/
System.out.println("導出財務版PDF文件");
return true;
}
}
----------------------------------------------------------------------------
public class FactoryTest {
public static void main(String[] args) {
String data = "";
ExportFactory exportFactory = new ExportHtmlFactory();
ExportFile ef = exportFactory.factory("financial");
ef.export(data);
}
}
與簡單工廠模式的對比:
1>工廠方法模式和簡單工廠模式在結構上的不一樣很明顯。工廠方法模式的核心是一個抽象工廠類,而簡單工廠模式把核心放在一個具體類上。

2>工廠方法模式退化後能夠變得很像簡單工廠模式。設想若是很是肯定一個系統只須要一個具體工廠類,那麼不妨把抽象工廠類合併到具體工廠類中去。因爲只有一個具體工廠類,因此不妨將工廠方法改成靜態方法,這時候就獲得了簡單工廠模式。
public class ConvertToSimpleFactory {
static ExportFile exportFile;
public static ExportFile factory(String construct, String type){
if ("HTML".equals(construct)) {
if("standard".equals(type)){
exportFile = new ExportStandardHtmlFile();
}else if("financial".equals(type)){
exportFile = new ExportFinancialHtmlFile();
}else{
throw new RuntimeException("沒有找到對象");
}
} else if ("PDF".equals(construct)) {
if("standard".equals(type)){
exportFile = new ExportStandardPdfFile();
}else if("financial".equals(type)){
exportFile = new ExportFinancialPdfFile();
}else{
throw new RuntimeException("沒有找到對象");
}
}
return exportFile;
}
}
public class FactoryTest {
public static void main(String[] args) {
String data = "";
ExportFile exportFile = ConvertToSimpleFactory.factory("HTML","financial");
exportFile.export(data);
}
}
3>若是系統須要加入一個新的導出類型,那麼所須要的就是向系統中加入一個這個導出類以及所對應的工廠類。沒有必要修改客戶端,也沒有必要修改抽象工廠角色或者其餘已有的具體工廠角色。對於增長新的導出類型而言,這個系統徹底支持「開-閉原則」。