工厂方法模式是一种更灵活的模式,它扩展了子类实例化的思想,即不再由单个工厂类决定到底应该实例化哪个子类。而超类则会将这一决定推迟到每个子类中完成。这种模式实际上不存在直接选择某个子类的决策点。使用这种模式编写的程序定义了一个抽象类(或者接口),虽然负责创建对象,但是应该创建哪个对象将由各个子类来决定。
工厂方法模式类图如下
(图片来源于参考文献1)
从上图可以看出,工厂方法模式涉及到以下的角色
抽象工厂接口(Creator) 担任这个角色的是工厂方法的核心,它是与应用程序无关,创建的工厂类必须实现该接口。
实工厂类 (Conrete Creator)
担任这个角色的是与应用程序紧密相关的,直接在程序的调用下创建具体的产品。
产品 (Product) 担任这个角色的是工厂方法模式所创建对象的父类,或者是必须实现的接口。
实产品 (Concrete Product) 担任这个角色的是工厂方法模式所创建对象所属的类。
工厂方法模式和简单工厂模式在定义上的不同是很明显的。工厂方法模式的核心是一个抽象工厂类,而不像简单工厂模式, 把核心放在一个实类上。工厂方法模式可以允许很多实的工厂类从抽象工厂类继承下来, 从而可以在实际上成为多个简单工厂模式的综合,从而推广了简单工厂模式。
反过来讲,简单工厂模式是由工厂方法模式退化而来。设想如果我们非常确定一个系统只需要一个实的工厂类, 那么就不妨把抽象工厂类合并到实的工厂类中去。而这样一来,我们就退化到简单工厂模式了。
工厂方法模式又叫多形性工厂模式,显然是因为实工厂类都有共同的接口,或者都有共同的抽象父类。
下面看看一个简单的例子:
//代码清单1 抽象工厂类(父类)
abstract public class Factory
{
public abstract Product factory(String name)throws BadProductException;
}
//代码清单2 工厂类A(子类)
public class FactoryA
{
Product factory(String name)throws BadProductException
{
if(name.equals(A!))
{
return new ProductA1();
}else if(name.equals("A2"))
{
return new ProductA2();
}else
throw new BadProductException(name);
}
}
//代码清单3 工厂类B(子类)
public class FactoryB
{
Product factory(String name)throws BadProductException
{
if(name.equals(B1))
{
return new ProductB1();
}else if(name.equals("B2"))
{
return new ProductB2();
}else
throw new BadProductException(name);
}
}
//代码清单4 产品类接口
public interface Product
{
void desc(); //产品描述
}
//代码清单5 实产品类(A2
,B1, B2与此类似
) public ProductA1 implements Product
{
public void desc()
{
System.out.println("this is product A1");
}
}
//代码清单6 异常类
public class BadProductException extends Exception
{
public BadProductException(String msg)
{
super(msg);
}
}
工厂方法的适用环境
1.类玩法预计出必须创建哪个类的对象。
2.类要使用其子类指定所要创建的对象。
3.对于将创建哪个类,希望将有关信息局部化。
工厂模式的几种不同形式
1.基类是抽象类,并且这种模式必须返回一个完全可工作的类。
2.基类包含默认方法,并且只有当默认的方法不够用时,才需要派生子类。
3.传递给工厂的参数将通知要返回哪些类类型。在这种情况下,所有的类必须有相同的方法名,当然每个方法完成不同的操作。
参考文献: 1.http://www.yesky.com/20011128/207301.shtml
2.<<java设计模式>>