工厂方法模式/Factory Method
意图/适用场景:
工厂类定义一个用于创建产品对象的接口,让子类决定实例化哪一个类。Factory Method使一个类的实例化延迟到其子类。
这一模式的特征是工厂类的子类继承树与产品类的子类继承树有一一对应的关系。
在下列情况下可以使用Factory Method模式:
- 当一个类不知道它所必须创建的对象的类的时候。
- 当一个类希望由它的子类来指定它所创建的对象的时候。
- 当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候。
UML:
参与者:
- 抽象产品(Product):定义工厂方法所创建的对象的接口。
- 具体产品(ConcreteProduct):实现Product接口。
- 抽象工厂类(Creator):声明工厂方法,该方法返回一个Product类型的对象。Creator也可以定义一个工厂方法的缺省实现,它返回一个缺省的ConcreteProduct对象。可以调用工厂方法以创建一个Product对象。
- 具体工厂类(ConcreteCreator):重定义工厂方法以返回一个ConcreteProduct实例。
应用实例:
考虑这样一个应用框架,两个主要的抽象是类Application和Document。这两个类都是抽象的,客户必须通过它们的子类来做与具体应用相关的实现。例如,为创建一个绘图应用,我们定义类DrawingApplication和DrawingDocument。
Application类负责管理Document并根据需要创建它们—例如,当用户从菜单中选择Open或New的时候。因为被实例化的特定Document子类是与特定应用相关的,所以Application类不可能预测到哪个Document子类将被实例化—Application类仅知道一个新的文档何时应被创建,而不知道哪一种Document将被创建。这就产生了一个尴尬的局面:框架必须实例化类,但是它只知道不能被实例化的抽象类。
Factory Method模式提供了一个解决办案。它封装了哪一个Document子类将被创建的信息并将这些信息从该框架中分离出来。Document继承树与Application继承树具有同样的结构,是一一对应的关系。
Application的子类重定义Application的抽象操作CreateDocument以返回适当的Document子类对象。一旦一个Application子类实例化以后,它就可以实例化与应用相关的文档,而无需知道这些文档的类。我们称CreateDocument是一个工厂方法(Factory Method),因为它负责“生产”一个对象。
示例代码:
[java]
// Source code from file:ConcreteCreatorA.java
packagedesignPatterns.FactoryMethod;
publicclass ConcreteCreatorA implements Creator {
publicProduct factory() {
returnnew ConcreteProductA();
}
}
// Source code from file:ConcreteCreatorB.java
packagedesignPatterns.FactoryMethod;
publicclass ConcreteCreatorB implements Creator {
publicProduct factory() {
returnnew ConcreteProductB();
}
}
// Source code from file:ConcreteProductA.java
packagedesignPatterns.FactoryMethod;
publicclass ConcreteProductA implements Product {
}
// Source code from file:ConcreteProductB.java
packagedesignPatterns.FactoryMethod;
publicclass ConcreteProductB implements Product {
}
// Source code from file:Creator.java
packagedesignPatterns.FactoryMethod;
publicinterface Creator {
publicProduct factory();
}
// Source code from file:Product.java
packagedesignPatterns.FactoryMethod;
publicinterface Product {
}
// Source code from file:User.java
packagedesignPatterns.FactoryMethod;
publicclass User {
publicstatic void main(String[] args) {
Creator creatorA =new ConcreteCreatorA();
Creator creatorB =new ConcreteCreatorB();
Product product = creatorA.factory();
System.out.println(product);
product = creatorB.factory();
System.out.println(product);
}
}
[/java]