工厂方法模式

2015-01-27 06:10:42 · 作者: · 浏览: 4

创建型模式

创建型模式抽象了实例化过程。它们帮助一个系统独立于如何创建、组合和表示它的那些对象。一个类创建型模式使用继承改变被实例化的类,而一个对象创建型模式将实例化委托给另一个对象。随着系统演化得越来越依赖于对象复合而不是类继承,创建型模式变得更为重要,创建型模式两个主旋律:

  • 它们都将关于该系统使用哪些具体的类的信息封装起来
  • 它们隐藏了这些类的实例是如何被创建和放在一起的

    工厂方法模式

    意图:定义一个创建对象的接口,让子类决定实例化哪一个类。Factory Method使一个类的实例化延迟到其子类。(类创建模式)
    动机:框架使用抽象类定义和维护对象之间的关系。这些对象的创建通常也由框架负责。
    适用性

    • 当一个类不知道它所必须创建的对象的类的时候
    • 当一个类希望由它的子类来指定它所创建的对象的时候
    • 当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候。

      结构
      Alt text

      • Product:定义了工厂方法所创建对象的接口
      • ConcreteProduct:实现Product接口
      • Creator:声明工厂方法,返回一个Product对象
      • ConcreteCreator:重定义工厂方法以返回一个ConcreteProduct

        协作:Creator依赖于它的子类来定义工厂方法,所以它返回一个适当的ConcreteProduct实例。

        缺陷:工厂方法的一个潜在缺点在于客户可能仅仅为了创建一个特定的ConcreteProduct对象,就不得不创建Creator的子类。当Creator子类不必需时,客户现在必然要处理类演化的其他方面;但是当客户无论如何必须创建Creator的子类时,创建子类也是可行的。

        实现

        • Creator可以是抽象类或接口,也可以是具体类提供默认工厂方法实现
        • Parameterized factory methods:工厂方法通过参数来判断创建哪一种对象产品
        • parallel factory methods:一组创建不同类型产品的方法,通过方法签名来区分
        • Connects parallel class hierarchies:一组层次化的产品可以通过相应层次化的工厂来创建对应相同层次的产品对象

          工厂方法模式的变种

          • 简单工厂模式:省略抽象工厂类,通过一系列静态方法提供创建相应的产品。JDK中实例:Executors提供静态方法来创建不同类型的线程池。
            简单工厂模式
          • 省略抽象工厂(Creator)和产品(Product),例如产品之间是没有联系的
          • 产品本身(Product)包含工厂方法来创建自己,例如java.text.DateFormat,这种比较少见DateFormat是一个抽象类,提供工厂方法返回的实例是其子类SimpleDateFormat。
            Alt text
          • 具体产品本身(ConcreteProduct)创建自己,如Singleton模式
          • 带有注册实例的工厂用于复用对象实例
            • Factory存储并创建对象实例于注册的对象池中(如Spring的Bean工厂)
            • 若需要可以重用已经注册的对象
            • 更进一步,对象不仅仅可以通过new方式创建,也可以从其他资源如数据库等(JDBC,JNDI和EJB)

              JDK中工厂方法模式

              • recognizeable by creational methods returning an implementation of an abstract/interface type
                • java.util.Calendar#getInstance():变种3,产品本身包含工厂方法,返回子类GregorianCalendar或其他
                • java.util.ResourceBundle#getBundle():变种3和5,采用了pool技术
                • java.text.NumberFormat#getInstance():变种3,返回子类DecimalFormat实例
                • java.nio.charset.Charset#forName()
                • java.net.URLStreamHandlerFactory#createURLStreamHandler(String) (Returns singleton object per protocol)
                • java.util.Collection#iterator is a good example of a Factory Method. Depending on the concrete subclass of Collection you use, it will create an Iterator implementation.