簡單工廠模式
一、模式動機與定義
模式動機
- 只需要知道水果的名字即可得到相應的水果
模式定義
- 簡單工廠模式(Simple Factory Pattern):又稱為靜態工廠方法模式,它屬於類創建型模式。
- 在簡單工廠模式中,可以根據參數的不同返回不同類的實例。
- 簡單工廠模式專門定義一個類來負責創建其他類的實例,被創建的實例通常都具有共同的父類。
二、模式結構與分析
模式結構
簡單工廠模式包含如下角色:
- Factory:工廠角色
- Product:抽象產品角色
- ConcreteProduct:具體產品角色
模式分析
- 將對象的創建和對象本身業務處理分離可以降低系統的耦合度,使得兩者修改起來都相對容易。
- 在調用工廠類的工廠方法時,由於工廠方法是靜態方法,使用起來很方便,可通過工廠類類名直接調用,只需要傳入一個簡單的參數即可,無需知道對象的創建細節。
- 可以將參數保存在XML等格式的配置文件中,修改時無需修改任何Java源代碼
- 問題:工廠類的職責相對過重,增加新的產品需要修改工廠類的判斷邏輯,違背開閉原則。
三、模式實例與解析
模式實例
簡單電視機工廠:實例說明
- 某電視機廠專為各知名電視機品牌代工生產各類電視機,當需要海爾牌電視機時只需要在調用該工廠的工廠方法時傳入參數"Haier",需要海信電視機時只需要傳入參數"Hisense",工廠可以根據傳入的不同參數返回不同品牌的電視機。現使用簡單工廠模式來模擬該電視機工廠的生產過程。
簡單電視機工廠:參考類圖
簡單電視機工廠:參考代碼
代碼結構:
TV接口
package simplefactory;
public interface TV {
public void play();
}
HaierTV類
package simplefactory;
public class HaierTV implements TV {
@Override
public void play() {
System.out.println("海爾電視機播放中···");
}
}
HisenseTV類
package simplefactory;
public class HisenseTV implements TV {
@Override
public void play() {
System.out.println("海信電視機播放中···");
}
}
TVFactory類
package simplefactory;
public class TVFactory {
public static TV produceTV(String brand) throws Exception{
if(brand.equalsIgnoreCase("Haier")){
System.out.println("電視機工廠生產海爾電視機!");
return new HaierTV();
}else if (brand.equalsIgnoreCase("Hisense")){
System.out.println("電視機工廠生產海信電視機!");
return new HisenseTV();
}else {
throw new Exception("對不起,暫不能生產該品牌電視機!");
}
}
}
XMLUtilTV類
package simplefactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.File;
public class XMLUtilTV {
//該方法用於從XML配置文件中提取品牌名稱,並返回該品牌名稱
public static String getBrandName() {
try {
//創建文檔對象
DocumentBuilderFactory dFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = dFactory.newDocumentBuilder();
Document doc;
doc = builder.parse(new File("D:\\MyNewWorld\\Study_JAVA\\MyHome\\Write_java\\My_Maven\\src\\main\\resources\\SimpleFactoryconfigTV.xml"));
//獲取包含品牌名稱的文本節點
NodeList n1 = doc.getElementsByTagName("brandName");
Node classNode = n1.item(0).getFirstChild();
String brandName = classNode.getNodeValue().trim();
return brandName;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
SimpleFactoryconfigTV.xml
<?xml version="1.0" encoding="UTF-8"?>
<config>
<brandName>Hisense</brandName>
</config>
Client類
package simplefactory;
public class Client {
public static void main(String[] args) {
try {
TV tv;
String brandName = XMLUtilTV.getBrandName();
tv = TVFactory.produceTV(brandName);
tv.play();
}catch (Exception e){
System.out.println(e.getMessage());
}
}
}
運行結果:
四、模式效果與應用
簡單工廠模式優點:
- 實現了對象創建和使用的分離
- 客戶端無須知道所創建的具體產品類的類名,只需要知道具體產品類所對應的參數即可。
- 通過引入配置文件,可以在不修改任何客戶端代碼的情況下更換和增加新的具體產品類,在一定程度上提高了系統的靈活性。
簡單工廠模式缺點:
- 工廠類集中了所有產品的創建邏輯,職責過重,一旦不能正常工作,整個系統都要受到影響。
- 增加系統中類的個數(引入了新的工廠類),增加了系統的復雜度和理解難度。
- 系統擴展困難,一旦添加新產品不得不修改工廠邏輯。
- 由於使用了靜態工廠方法,造成工廠角色無法形成基於繼承的等級結構,工廠類不能得到很好地擴展。
在以下情況下可以使用簡單工廠模式:
- 工廠類負責創建的對象比較少:由於創建的對象較少,不會造成工廠方法中的業務邏輯太過復雜。
- 客戶端只知道傳入工廠類的參數,對於如何創建對象不關心:客戶端既不需要關心創建細節,甚至連類名都不需要記住,只需要知道類型所對應的參數。
