JAVA設計模式之Factory 方法模式

來源:互聯網
上載者:User

標籤:

在閻宏博士的《JAVA與模式》一書中開頭是這樣描述Factory 方法模式的:

  Factory 方法模式是類的建立模式,又叫做虛擬構造子(Virtual Constructor)模式或者多態性工廠(Polymorphic Factory)模式。

  Factory 方法模式的用意是定義一個建立產品對象的工廠介面,將實際建立工作延遲到子類中。

那麼Factory 方法模式是在什麼情境下使用呢,下面就以本人的理解舉例說明:

  相信很多人都做過匯入匯出功能,就拿匯出功能來說。有這麼一個需求:XX系統需要支援對資料庫中的員工薪資進行匯出,並且支援多種格式如:HTML、CSV、PDF等,每種格式匯出的結構有所不同,比如:財務跟其他人對匯出薪資的HTML格式要求可能會不一樣,因為財務可能需要特定的格式方便核算或其他用途。

  如果使用簡單原廠模式,則工廠類必定過於臃腫。因為簡單原廠模式只有一個工廠類,它需要處理所有的建立的邏輯。假如以上需求暫時只支援3種匯出的格式以及2種匯出的結構,那工廠類則需要6個if else來建立6種不同的類型。如果日後需求不斷增加,則後果不堪設想。

  這時候就需要Factory 方法模式來處理以上需求。在Factory 方法模式中,核心的工廠類不再負責所有的對象的建立,而是將具體建立的工作交給子類去做。這個核心類則搖身一變,成為了一個抽象工廠角色,僅負責給出具體工廠子類必須實現的介面,而不接觸哪一個類應當被執行個體化這種細節。

  這種進一步抽象化的結果,使這種Factory 方法模式可以用來允許系統在不修改具體工廠角色的情況下引進新的產品,這一特點無疑使得Factory 方法模式具有超過簡單原廠模式的優越性。下面就針對以上需求設計UML圖:

  從可以看出,這個使用的Factory 方法模式的系統涉及到以下角色:

 

  抽象工廠(ExportFactory)角色:擔任這個角色的是Factory 方法模式的核心,任何在模式中建立對象的工廠類必須實現這個介面。在實際的系統中,這個角色也常常使用抽象類別實現。

  具體工廠(ExportHtmlFactory、ExportPdfFactory)角色:擔任這個角色的是實現了抽象工廠介面的具體JAVA類。具體工廠角色含有與業務密切相關的邏輯,並且受到使用者的調用以建立匯出類(如:ExportStandardHtmlFile)。

  抽象匯出(ExportFile)角色:Factory 方法模式所建立的對象的超類,也就是所有匯出類的共同父類或共同擁有的介面。在實際的系統中,這個角色也常常使用抽象類別實現。

  具體匯出(ExportStandardHtmlFile等)角色:這個角色實現了抽象匯出(ExportFile)角色所聲明的介面,Factory 方法模式所建立的每一個對象都是某個具體匯出角色的執行個體。

原始碼

  首先是抽象工廠角色原始碼。它聲明了一個Factory 方法,要求所有的具體工廠角色都實現這個Factory 方法。參數type表示匯出的格式是哪一種結構,如:匯出HTML格式有兩種結構,一種是標準結構,一種是財務需要的結構。

public interface ExportFactory {
public ExportFile factory(String type);
}

  具體工廠角色類原始碼:

public class ExportHtmlFactory implements ExportFactory{

@Override
public ExportFile factory(String type) {
// TODO Auto-generated method stub
if("standard".equals(type)){

return new ExportStandardHtmlFile();

}else if("financial".equals(type)){

return new ExportFinancialHtmlFile();

}else{
throw new RuntimeException("沒有找到對象");
}
}

}
public class ExportPdfFactory implements ExportFactory {

@Override
public ExportFile factory(String type) {
// TODO Auto-generated method stub
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 ExportFinancialHtmlFile implements ExportFile{

@Override
public boolean export(String data) {
// TODO Auto-generated method stub
/**
* 商務邏輯
*/
System.out.println("匯出財務版HTML檔案");
return true;
}

}
public class ExportFinancialPdfFile implements ExportFile{

@Override
public boolean export(String data) {
// TODO Auto-generated method stub
/**
* 商務邏輯
*/
System.out.println("匯出財務版PDF檔案");
return true;
}

}
public class ExportStandardHtmlFile implements ExportFile{

@Override
public boolean export(String data) {
// TODO Auto-generated method stub
/**
* 商務邏輯
*/
System.out.println("匯出標準HTML檔案");
return true;
}

}
public class ExportStandardPdfFile implements ExportFile {

@Override
public boolean export(String data) {
// TODO Auto-generated method stub
/**
* 商務邏輯
*/
System.out.println("匯出標準PDF檔案");
return true;
}

}

用戶端角色類原始碼:

public class Test {

/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
String data = "";
ExportFactory exportFactory = new ExportHtmlFactory();
ExportFile ef = exportFactory.factory("financial");
ef.export(data);
}

}
Factory 方法模式的活動順序圖表

  用戶端建立ExportHtmlFactory對象,這時用戶端所持有變數的靜態類型為ExportFactory,而實際類型為ExportHtmlFactory。然後用戶端調用ExportHtmlFactory對象的Factory 方法factory(),接著後者調用ExportFinancialHtmlFile的構造子建立出匯出對象。

Factory 方法模式和簡單原廠模式

  Factory 方法模式和簡單原廠模式在結構上的不同很明顯。Factory 方法模式的核心是一個抽象工廠類,而簡單原廠模式把核心放在一個具體類上。
  Factory 方法模式退化後可以變得很像簡單原廠模式。設想如果非常確定一個系統只需要一個具體工廠類,那麼不妨把抽象工廠類合并到具體工廠類中去。由於只有一個具體工廠類,所以不妨將Factory 方法改為靜態方法,這時候就得到了簡單原廠模式。

  如果系統需要加入一個新的匯出類型,那麼所需要的就是向系統中加入一個這個匯出類以及所對應的工廠類。沒有必要修改用戶端,也沒有必要修改抽象工廠角色或者其他已有的具體工廠角色。對於增加新的匯出類型而言,這個系統完全支援“開-閉原則”。
  

完結

  一個應用系統是由多人開發的,匯出的功能是你實現的,但是使用者(調用這個方法的人)可能卻是其他人。這時候你應該設計的足夠靈活並儘可能降低兩者之間的耦合度,當你修改或增加一個新的功能時,使用者不需要修改任何地方。假如你的設計不夠靈活,那麼將無法面對客戶多變的需求。可能一個極小的需求變更,都會使你的代碼結構發生改變,並導致其他使用你所提供的介面的人都要修改他們的代碼。牽一處而動全身,這就使得日後這個系統將難以維護。

  






JAVA設計模式之Factory 方法模式

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.