設計模式的藝術 工廠方法模式
不懂使用為學過,說出用途,繪製結構為了解,不會靈活使用基本等於沒學。
前言
工廠方法模式是簡單工廠模式的延伸,它繼承了簡單工廠方法模式的優點,同時還彌補了簡單工廠方法模式的不足,
工廠方法模式是使用頻率最高的設計模式之一,是很多開源框架API類庫的核心模式
工廠方法模式的定義(Factory Method Pattern)
定義一個使用者建立物件的介面,讓子類決定將哪一個類例項化,工廠方法模式讓一個類的例項化延遲到其子類,工廠方法模式又被稱為工廠模式(Factory Pattern),有可以稱為虛擬構造器模式(Virtual Constructor Pattern)或者多型工廠模式(Polymorphic Factory Pattern)。工廠方法模式是一種類建立型模式
工廠方法模式的優點
(1)、在工廠方法模式中,工廠方法用來建立客戶所需要的產品,同時還隱藏了那個具體產品類將被例項化這一個實現細節,使用者只需要關注所需產品對應的工廠,無須關心建立細節,甚至無須知道具體產品類的類名
(2)、基於工廠角色和產品角色的多型性設計是工廠模式的關鍵,它能讓工廠可以自主確定建立何種產品物件,而如何建立這個物件的細節則完全封裝在具體工廠的內部,工廠方法模式又被稱之為多型工廠模式,正是因為所有的具體工廠類都具有同一個抽象父類
(3)、工廠方法模式最大的優勢在於系統新增產品時,無須修改抽象工廠和抽象產品提供的介面,只需要加上一個具體產品和對應的工廠即可,這樣子系統的擴充套件性也非常的好,完全符合了開閉原則
工廠方法模式的缺點
(1)、新增產品時,除了編寫新的具體產品類,還需要提供與之相對應的具體工廠類,這樣一定程度上增加了系統的複雜程度,有更多的類需要編譯和執行,會給系統帶來一些額外開銷
(2)、考慮到系統的可擴充套件性,會引入抽象層,在客戶端程式碼中皆使用抽象層定義,會增加系統的抽象性和理解難度,且在實現的時候可能需要用到DOM,反射技術,增加了系統的實現難度
工廠方法模式的應用場景
(1)、客戶端不需要知道其所需要的物件的類。因為在工廠方法模式中,客戶端不需要知道具體產品類的類名,只需知道對應工廠即可
(2)、抽象工廠通過其子類來確定建立哪個物件,在抽象工廠類中只需要提供一個建立產品的介面,而尤其子類來確定具體建立的物件,利用面向物件的多型性和里氏替換原則,在程式執行時,子類物件覆蓋父類物件,從而使系統更加容易擴充套件
工廠方法模式的具體實現
簡單的工廠模式的實現
Factory的介面
//工廠類的介面
public interface LoggerFactory {
Logger createLogger();
}
Factory的具體實現
public class FileLoggerFactory implements LoggerFactory {
@Override
//具體產品
public Logger createLogger() {
Logger logger=new FileLogger();
return logger;
}
}
public class DatabaseLoggerFactory implements LoggerFactory {
@Override
public Logger createLogger() {
Logger logger=new DatabaseLogger();
return logger;
}
}
//輔助工具類,使用xml配置檔案和反射技術增加程式的擴充套件性
public class XMLUtil {
public static Object getBean(){
try {
//建立DOC物件
DocumentBuilderFactory builderFactory=DocumentBuilderFactory.newInstance();
DocumentBuilder builder=builderFactory.newDocumentBuilder();
Document document=builder.parse(new File(XMLUtil.class.getClassLoader().getResource("").getPath()+"config.xml"));
//獲取包含類名的文字節點
NodeList nodeList=document.getElementsByTagName("className");
Node node =nodeList.item(0).getFirstChild(); //獲取第一位該節點值
//通過類名生成例項物件並將其返回
Class c=Class.forName(String.valueOf(node));
Object o=c.newInstance();
return o;
}catch (Exception e){
e.printStackTrace();
return null;
}
}
}
//所有產品的介面
//抽象產品
public interface Logger {
void writeLog();
}
//產品的具體實現
public class FileLogger implements Logger {
@Override
public void writeLog() {
System.out.println("檔案日誌記錄");
}
}
public class DatabaseLogger implements Logger {
@Override
public void writeLog() {
System.out.println("資料庫日誌記錄");
}
}
//測試類
public class Main {
public static void main(String[] args) {
LoggerFactory loggerFactory;
Logger logger;
loggerFactory=(LoggerFactory)XMLUtil.getBean(); //返回OBJECT,需要強制轉換
logger=loggerFactory.createLogger();
logger.writeLog();
}
}
轉載請註明出處,掌聲送給社會人