【設計模式筆記】建立型--工廠方法模式

工廠模式說明

定義一個用於建立對象的接口,讓子類決定將那一個類實例化;  工廠方法讓類的實例化延遲到子類。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,充分考慮靈活和可擴展性

相關文章
相關標籤/搜索