1. 程式人生 > >設計模式之三:工廠方法模式—多型工廠的實現

設計模式之三:工廠方法模式—多型工廠的實現

簡單工廠的嚴重問題: 當系統中需要引進新產品時,靜態工廠方法通過所傳入引數的不同來建立不同的產品,這必定要修改工廠類的原始碼,違背了開閉原則 引入工廠方法模式: 針對不同的產品提供不同的工廠 定義: 定義一個用於建立物件的介面,讓子類決定將 哪一個類例項化,工廠方法迷失讓一個類例項化延遲到其子類,工廠方法模式又稱為工廠模式(Factory Pattern),又課稱作虛擬構造器模式(VIrtual Constructor Pattern) 一、工廠方法模式概述: 引入抽象工廠角色,可以是介面,也可以是抽象類或者具體類 程式碼: interface Factory{     public Product factoryMethod(); } class ConcreteFactory implements Factory{     public Product factoryMethod(){         return new COncreteFactory();     } } 二、完整解決方案: interface Logger{     public void writeLog(); } class DatabaseLogger implements Logger{     public void writeLog(){         System.out.println("資料庫寫日誌");     } } class FileLogger implements Logger{     public void writeLog(){         System.out.println("檔案寫日誌");     } } interface LoggerFactory{     public Logger createLogger(); } class DatabaseLoggerFactory implements Factory{     public Logger createLogger(){         Logger logger =new DatabaseLogger();         return logger();     } } class FileLoggerFactory implements Factory{     public Logger createLogger(){         Logger logger=new FileLogger();         return logger;     } } class Client{     public static void main(String[] args) {         LoggerFactory factory;         Logger logger;         factory=new FileLoggerFactory();         logger=factory.createLogger();         logger.writeLog()     } } 三、反射與配置檔案
利用反射,返回xml中指定的物件,這樣修改就不用修改原始碼了。 <?xml version="1.0"?> <config>     <chartType>histogram</chartType> </config> import javax.xml.parsers.*; import org.w3c.dom.*; import org.xml.sax.SAXException; import java.io.*; class XMLUtil{     public static String getChartType(){         try{             DocumentBuilderFactory dFactory=DocumentBuilderFactory.newInstance();             DocumentBuilder builer=dFactory.newDocumentBuilder();             Document doc;             doc=builer.parse(new File("config.xml"));             NodeList nl=doc.getElementsByTagName("className");             Node classNode=nl.item(0).getFirstChild();             String cName=classNode.getNodeValue();             Class c=Class.forName(cName);             Object obj=c.newInstance();             return obj;             }         catch(Exception e){             e.printStackTrace();             return null;         }     }     } Client端修改如下: class Client{     public static void main(String[] args) {         LoggerFactory factory;         Logger logger;         factory=(LoggerFactory)XMLUtil.getBean;         logger=factory.createLogger();         logger.writeLog()     }  四、過載的工廠方法
使用工廠建立物件時,建立方法可以過載,使用args引數,obj引數,預設方式等多種引數來建立工廠 class DatabaseLoggerFactory implements Factory{     public Logger createLogger(){         Logger logger =new DatabaseLogger();         return logger();     }     public Logger createLogger(String args){         Logger logger =new DatabaseLogger();         return logger();     }     public Logger createLogger(Object obj){         Logger logger =new DatabaseLogger();         return logger();     } } 五、工廠方法模式總結:
  1. 主要優點:
    1. 用火狐只需關心產品對應的工廠,無需關心建立細節,甚至具體產品的類的類名
    2. 多型,所有具體工廠類都具有同一個父類
    3. 加入新產品時,無需修改抽象工廠和抽象產品聽的介面,無需修改客戶端,也無需修改其他的具體工廠和具體產品,而指套新增一個具體工廠和具體產品就可以了,擴充套件性好
  2. 主要缺點:
    1. 新增新產品時徐太編寫新的具體產品類
    2. 為了擴充套件性,需要引入抽象層,增加系統的抽象性和理解難度,增加了實現的難度
  3. 適用場景:
    1. 客戶端不知道其所需要的物件的類
    2. 抽象工廠類通過其子類來指定建立那個物件