【设计模式笔记】建立型--工厂方法模式

工厂模式说明

定义一个用于建立对象的接口,让子类决定将那一个类实例化;  工厂方法让类的实例化延迟到子类。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,充分考虑灵活和可扩展性

相关文章
相关标签/搜索