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