定義一個用於建立對象的接口,讓子類決定將那一個類實例化; 工廠方法讓類的實例化延遲到子類。java
Product: 抽象產品類node
ConcreteProduct:數據庫
Factory:抽象工廠,聲明工廠方法 Factory Method,用戶返回一個產品;抽象工廠是工廠方法模式的核心測試
ConcreteFactory:實現抽象工廠中定義的工廠方法,並由客戶端調用,返回一個具體產品類實例ui
實際使用時,具體工廠類在實現工廠方法時,除了建立具體產品對象外,還能夠負責對象的初始化工做及一些資源和環境配置工做,好比鏈接數據庫、建立文件等。設計
interface Factory{ public Product factoryMethod(); } class ConcreteFactory implements Factory{ public Product factoryMethdo() { return new ConcreteProduct(); } } 客戶端代碼樣例: .... Factory factory; factory = new ConcreteFactory(); --- 可經過配置文件實現(配置文件存儲實例具體工廠類類名)經過反射來實現類的實例化 Product product; product = factory.factoryMethod(); ...
日誌記錄器日誌
一、類圖xml
public interface Logger { public void writerLog(); } public class FileLogger implements Logger{ public void writerLog() { System.out.println("文件日誌記錄"); } } public class DatabaseLogger implements Logger{ public void writerLog() { System.out.println("數據庫記錄日誌"); } }
public interface LoggerFactory { public Logger createLogger(); } public class DatabaseLoggerFactory implements LoggerFactory { public Logger createLogger() { // 鏈接數據庫 Logger logger = new DatabaseLogger(); return logger; } } public class FileLoggerFactory implements LoggerFactory { public Logger createLogger() { Logger logger = new FileLogger(); return logger; } }
public class XMLUtil { public static Object getBean() { try { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); Document doc; doc = builder.parse(new File( System.getProperty("user.dir") + File.separator + "resource" + File.separator + "config.xml")); NodeList nodeList = doc.getElementsByTagName("className"); Node classNode = nodeList.item(0).getFirstChild(); String className = classNode.getNodeValue(); Class clazz = Class.forName("creation.factoryMethod.FileLoggerFactory"); //Class clazz = Class.forName(className); Object object = clazz.newInstance(); return object; } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); return null; } } }
最終客戶端代碼對象
public class Client { public static void main(String[] args) { // LoggerFactory factory = new FileLoggerFactory(); // Logger logger = factory.createLogger(); // logger.writerLog(); // 常見方式:藉助讀取配置文件+反射,實現動態的調整 LoggerFactory factory = (LoggerFactory)XMLUtil.getBean(); Logger logger = factory.createLogger(); logger.writerLog(); } }
config.xml配置文件blog
<?xml version="1.0" encoding="UTF-8"?> <config> <className>FileLoggerFactory</className>
<!-- 目前代碼這裏直接讀取類名沒法實現類的實例化提示空異常,因此目前java代碼使用包名+類名全路徑模擬測試 --> </config>
優勢:
1)工廠方法用於建立客戶所需的產品,同時隱藏了哪一個具體產品類被實例化的細節;用戶只須要關注所需產品對應的工廠,無需知道具體產品的類名;
2)基於工廠角色和產品角色的多態性,是工廠方法模式的關鍵。能夠讓工廠自主肯定建立何種產品對象。
3)加入新產品時,無需修改抽象工廠和抽象工廠提供的接口;無需修改客戶端
缺點:
1)添加新產品,須要新增產品類和對應的產品工廠類;
2)考慮到擴展性,會引入抽象層。客戶端代碼均使用抽象層代碼,增長理解難度;同時實現時可能用到DOM和反射技術,增長系統實現難度。
1)客戶端不知道要具體實例化的類;
工廠方法實現一個程序用於讀取不一樣類型的圖片格式,針對每種圖片都設計一種讀取器,好比JPG,好比GIF,充分考慮靈活和可擴展性