工厂方法模式
创建型模式
UML
说明:
- Creator:抽象创建器。其核心是声明工厂方法 factoryMethod,该方法返回一个产品。任何在模式中创建对象的具体创建器类必须实现这个接口
- ConcreteCreator:具体创建器。实现抽象创建器的具体类,实现了工厂方法,含有与应用密切相关的逻辑,由客户调用返回一个产品实例。
- Product:抽象产品,定义产品接口。工厂方法模式所创建的对象的父类型,产品对象共同拥有的接口。
- ConcreteProduct:具体产品。实现抽象产品角色接口的类,工厂方法模式所创建的每一个对象都是某个具体产品角色的实例。某种类型的具体产品由专门的具体创建器创建,他们之间往往一一对应。
代码示例
// 创建器角色
abstract class Creator{
public Creator(){}
// 工厂方法
public abstract Product factoryMethod();
// 其他方法
public void anOperation(){
Product product = factoryMethod();
product.anProductOperation();
}
}
// 具体创建器角色
class ConcreteCreator1 extends Creator{
public ConcreteCreator1(){}
public Product factoryMethod(){
return new ConcreteProduct1();
}
}
class ConcreteCreator2 extends Creator{
public ConcreteCreator2(){}
public Product factoryMethod(){
return new ConcreteProduct2();
}
}
// 抽象产品角色
interface Product{
void anProductOperation();
}
// 具体产品角色
class ConcreteProduct1 implements Product{
public ConcreteProduct1(){
System.out.println("ConcreteProduct1 be constructed");
}
public void anProductOperation(){
System.out.println("ConcreteProduct1's operation");
}
}
class ConcreteProduct2 implements Product{
public ConcreteProduct2(){
System.out.println("ConcreteProduct2 be constructed");
}
public void anProductOperation(){
System.out.println("ConcreteProduct2's operation");
}
}
// 测试程序
class Test{
public static void main(String[] args){
// 创建器
Creator creator1,creator2;
creator1 = new ConcreteCreator1();
creator2 = new ConcreteCreator2();
// 创建产品供而客户端使用
Product product1,product2;
product1 = creator1.factoryMethod();
product2 = creator2.factoryMethod();
// 方法调用,创建的产品只供创建器本身使用
product1.anProductOperation();
product2.anProductOperation();
creator1.anOperation();
creator2.anOperation();
}
}
综述
工厂方法模式是简单工厂模式的进一步抽象和推广。基于创建器角色和产品角色的多态性设计是工厂方法模式的关键。它使具体创建器可以自主确定创建何种产品对象,而如何创建这个对象的细节则完全封装在具体创建器内部。
工厂方法模式保持了简单工厂模式的优点,克服了它的缺点。在工厂方法模式中,核心的创建器类不再负责素有产品的创建,而是将具体创建工作交给子类去做。核心类仅仅负责给出具体创建器必须实现的接口,而不负责哪个产品类被实例化这种细节,这使得工厂方法模式可以允许系统在不修改工厂角色的情况下引入新产品
当系统扩展需要添加新的产品对象时,仅仅需要添加一个具体产品对象以及一个具体创建器对象。
为了提高系统的可扩展性和灵活性,在定义创建器和产品时都必须使用抽象层,如果需要更换产品类,只需更换对应的创建器即可。
优点
工厂方法用来创建客户需要的产品,同时还向客户隐藏了哪种具体产品类将被实例化这一细节。
系统的可扩展性非常好。
缺点
在添加新产品时,需要编写具体产品类,而且要提供与之对应的具体创建器类,系统中类的个数成对增加,在一定程度上增加了系统的复杂度,有更多的类需要编译运行,会给系统带来额外的开销。
由于考虑到系统的可扩展性,需要引入抽象层,在客户端代码中均使用抽象层进行定义,增加了系统的抽象性和理解难度。