[关闭]
@pastqing 2015-10-09T09:55:52.000000Z 字数 4011 阅读 3892

java设计模式——工厂方法模式

java 设计模式


前言

应用场景: 在上篇的简单工厂模式中, 我们使用了一个工厂类来创建产品。我们对其做一下修改, 不再设计一个报文工厂类来负责所有产品的创建了, 而是将具体产品的创建过程交给专门的工厂子类来完成。我们预先定义一个抽象工厂类, 然后利用具体的工厂类来分别生成产品(报文种类1, 报文种类2, ...)。 这样做的好处显而易见, 如果出现新类型的报文, 只需要为这种新类型创建一个具体的工厂类即可, 符合了开闭原则。

工厂方法模式的定义

工厂方法(Factory Method)模式的意义是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中。核心工厂类不再负责产品的创建,这样核心类成为一个抽象工厂角色,仅负责具体工厂子类必须实现的接口,这样进一步抽象化的好处是使得工厂方法模式可以使系统在不修改具体工厂角色的情况下引进新的产品。
它包含了如下角色:

工厂方法模式的应用

场景代码示例

抽象产品类

  1. public abstract class AnswerHead {
  2. protected String request_type;
  3. protected String agent_code;
  4. protected String trn_code;
  5. protected String front_traceno;
  6. public abstarct String toXML();
  7. }

具体产品类

  1. /** 产品类1, 只有应答报文头 **/
  2. public class AnswerHeadOnly extends AnswerHead {
  3. public String toXML() {
  4. System.out.println("AnswerHeadOnly to xml");
  5. return null;
  6. }
  7. }
  1. /**产品类2, 业务1应答报文体 **/
  2. public class AnswerBody_Mobile extends AnswerHead {
  3. public String toXML() {
  4. System.out.println(" AnswerBody_Mobile to xml");
  5. return null;
  6. }
  7. }

抽象工厂接口

  1. public interface ProductFactory {
  2. public AnswerHead createProduct();
  3. }

具体工厂类

  1. public class AnswerBody_Mobile_Factory implements ProductFactory {
  2. public AnswerHead createProduct() {
  3. return new AnswerBody_Mobile();
  4. }
  5. }

测试类

  1. public static void main(String[] args) {
  2. ProductFactory factory = new AnswerBody_Mobile_Factory();
  3. AnswerHead am = factory.createProduct();
  4. am.toXML();
  5. }

运用了工厂方法模式, 我们之前的if else被不同类型的具体工厂类所取代, 这样在增加新的产品的时候不用修改原来的代码, 增加了可维护性。 当然这样做的后果就是项目中多了很多的类和接口, 增加了系统复杂性。

工厂方法模式在JDBC API中的应用

JDBC是JDK提供的标准化数据接口, 各大数据库厂商都实现了JDBC API, JDBC是使用工厂方法模式的呢, 我们关注1个类和3个接口,

工厂方法模式日志记录中的应用

一般系统中的日志记录器可以使用工厂方法模式来设计, 如下图:
此处输入图片的描述

总结


附:静态工厂方法

静态工厂方法不是设计模式, 它是我们常用的一些编码技巧, Effective java第一条就介绍了它的用法, 这里记录一下。

来看一个JDK中的例子:

  1. public final class Boolean implements java.io.Serializable,
  2. Comparable<Boolean> {
  3. //这里缓存了两个对象
  4. public static final Boolean TRUE = new Boolean(true);
  5. public static final Boolean FALSE = new Boolean(false);
  6. public static Boolean valueOf(boolean b) {
  7. return (b ? TRUE : FALSE);
  8. }
  9. }

这里public static Boolean valueOf 就是一个静态工厂方法, 它的作用是用来产生一个Boolean对象

静态工厂方法的优势

  1. public static Integer valueOf(int i) {
  2. assert IntegerCache.high >= 127;
  3. if (i >= IntegerCache.low && i <= IntegerCache.high)
  4. return IntegerCache.cache[i + (-IntegerCache.low)];
  5. return new Integer(i);
  6. }

上面的代码是Integer的valueOf方法, 可以看出它做了一个cache缓存。这个方法将总是缓存 -128 到 127的值, 每次从缓存中获取对象, 而不是重新new一个

  1. Map<String, List<String>> m = new HashMap<String, List<String>>();

以上代码非常复杂丑陋, 静态工厂方法帮我们解决:

  1. public static <K, V> HashMap<K, V> newInstance() {
  2. return new HashMap<K, V>();
  3. }

静态工厂方法的缺陷

参考文献:
工厂方法模式
工厂方法模式(Factory Method Pattern)
Effective 中的静态工厂方法

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注