以下是读《设计模式——可复用面向对象软件的基础》的读书笔记。
FACTORY METHOD工厂方法
1、 意图
定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method使一个类的实例化延迟到其子类。
2、 别名
虚构造器(Virtual Constructor)
3、 适用性
在下面情况下可以使用Factory Method模式:
4、 结构
5、 参与者
Product
——定义工厂方法所创建的对象的接口。
ConcreteProduct
——实现Product接口。
Creator
——声明工厂方法,该方法返回一个Product类型的对象。Creator也可以定义一个工厂方法的缺省实现,它返回一个缺省的ConcreteProduct对象。
——可以调用工厂方法以创建一个Product对象。
ConcreteCreator
——重定义工厂方法以返回一个ConcreteProduct实例。
6、 协作
Creator依赖于它的子类来定义工厂方法,所以它返回一个适当的ConcreteProduct实例。
7、 效果
工厂方法不再将与特定应用有关的类绑定到你的代码中。代码仅处理Product接口;因此它可以与用户定义的任何ConcreteProduct类一起使用。
工厂方法的一个潜在缺点在于客户可能仅仅为了创建一个特定的ConcreteProduct对象,就不得不创建Creator的子类。当Creator子类不必需时,客户现在必然要处理类演化的其他方面;但是当客户无论如何必须创建Creator的子类时,创建子类也是可行的。
下面是FactoryMethod貌似的另外两种效果:
1)为子类提供挂钩(hook) 用工厂方法在一个类的内部创建对象通常比直接创建对象更灵活。Factory Method给子类一个挂钩以提供对象的扩展版本。
2)连接平行的类层次 当一个类将它的一些职责委托给一个独立的类的时候,就产生了平行类的层次。工厂方法并不往往只是被Creator调用,客户可以找到一些有用的工厂方法。
8、 实现
当应用Factory Method模式时要考虑下面问题:
1) 主要有两种不同的情况 Factory Method模式主要有两种不同的情况:A第一种情况是,Creator类是一个抽象类并且不提供它所声明的工厂方法的实现。B第二种情况是,Creator是一个具体的类而且为工厂方法提供一个缺省的实现。
第一种情况需要子类来定义实现,因为没有合理的缺省实现。它避免了不得不实例化不可预见类的问题。
第二种情况中,具体的Creator主要因为灵活性才使用工厂方法。它所遵循的准则是,“用一个独立的操作创建对象,这样子类才能重定义它们的创建方式。”这条准则保证了子类的设计者能够在必要的时候改变父类所实例化的对象的类。
2) 参数化工厂方法 该模式的另一种情况使得工厂方法可以创建多种产品。工厂方法采用一个标识要被创建的对象种类的参数。工厂方法创建的所有对象将共享Product接口。
9、 示例
package com.examples.pattern.factoryMethod;
/**
* 工厂方法所创建的对象的接口
*/
public interface Product {
/**
* 定义的一些方法
*/
public void operate();
}
ConcreteProduct
package com.examples.pattern.factoryMethod;
/**
* 具体的Product对象
*/
public class ConcreteProduct implements Product {
@Override
public void operate() { //具体实现...
System.out.println("operate ....");
}
}
Creator
package com.examples.pattern.factoryMethod;
/**
* 创建器,声明工厂方法
*/
public abstract class Creator {
/**
* 创建Product的工厂方法
* @return Product对象
*/
protected abstract Product factoryMethod();
/**
* 示例方法,完成一些操作...
*/
public void someOperation(){
//通常在这些方法中需要调用工厂方法来获得Product对象。
//获得是其子类定义的对象...
Product product = factoryMethod();
product.operate(); //一些操作...
}
}
package com.examples.pattern.factoryMethod;
/**
* 具体的创建器实现对象
*/
public class ConcreteCreater extends Creator {
@Override
protected Product factoryMethod() {
//重定义工厂方法,返回一个具体的Product实例。
return new ConcreteProduct();
}
}
Client
package com.examples.pattern.factoryMethod;
public class Client {
public static void main(String[] args) {
Creator creator = new ConcreteCreater();
creator.someOperation();
}
}
10、 相关模式
Abstract Factory经常用工厂方法来实现。
工厂方法通常在Template Method中被调用。
Prototypes不需要创建Creator子类。但是,他们通常要求一个针对Product类的Initialize操作。Creator使用Initialize来初始化对象。而Factory Method不需要这样的操作。