在设计模式中,Factory Method也是比较简单的一个,但应用非常广泛,EJB,RMI,COM,CORBA,Swing中都可以看到此模式的影子,它是最重要的模式之一。
作者:中国IT实验室 来源:中国IT实验室 2007年8月26日
关键字:
1.c 定义抽象的创建器,anOperation调用factoryMethod创建一个对象,并对该对象进行一系列操作。
abstract class ShapeFactory
{
protected abstract Shape
factoryMethod(String aName);
// 在anOperation中定义Shape的一系列行为
public void anOperation(String aName)
{
Shape s = factoryMethod(aName);
System.out.println
("The current shape is: " + s.name);
s.draw();
s.erase();
}
}
1.d 定义与circle和square相对应的两个具体创建器CircleFactory,SquareFactory,实现父类的methodFactory方法
// 定义返回 circle 实例的 CircleFactory
class CircleFactory extends ShapeFactory
{
// 重载factoryMethod方法,返回Circle对象
protected Shape factoryMethod(String aName)
{
return new Circle(aName + "
(created by CircleFactory)");
}
}
// 定义返回 Square
实例的 SquareFactory
class SquareFactory extends ShapeFactory
{
// 重载factoryMethod方法,返回Square对象
protected Shape factoryMethod(String aName)
{
return new Square
(aName + " (created by SquareFactory)");
}
}
1.e 测试类:请注意这个客户端程序多么简洁,既没有罗嗦的条件判断语句,也无需关心ConcreteProduct和ConcreteCreator的细节(因为这里我用anOperation封装了Product里的两个方法,所以连Product的影子也没看见,当然把Product里方法的具体调用放到客户程序中也是不错的)。
class Main
{
public static void main(String[] args)
{
ShapeFactory sf1 = new SquareFactory();
ShapeFactory sf2 = new CircleFactory();
sf1.anOperation("Shape one");
sf2.anOperation("Shape two");
}
}
运行结果如下:
The current shape is: Shape one
(created by SquareFactory)
It will draw a square.
It will erase a square.
The current shape is: Shape two
(created by CircleFactory)
It will draw a circle.
It will erase a circle.
参数化的Factory Method: 这种方式依靠指定的参数作为标志来创建对应的实例,这是很常见的一种办法。比如JFC中的BorderFactory就是个很不错的例子。
以下的这个例子是用字符串作为标记来进行判断的,如果参数的类型也不一样,那就可以用到过载函数来解决这个问题,定义一系列参数和方法体不同的同名函数,这里java.util.Calendar.getInstance()又是个极好的例子。
参数化的创建方式克服了Factory Method模式一个最显著的缺陷,就是当具体产品比较多时,我们不得不也建立一系列与之对应的具体构造器。 但是在客户端我们必须指定参数来决定要创建哪一个类。
2.a 我们在第一种方法的基础上进行修改,首先自定义一个的异常,这样当传入不正确的参数时可以得到更明显的报错信息。
class NoThisShape extends Exception
{
public NoThisShape(String aName)
{
super(aName);
}
}
2.b 去掉了ShapeFactory的两个子类,改为由ShapeFactory直接负责实例的创建。 ShapeFactory自己变成一个具体的创建器,直接用参数化的方法实现factoryMethod返回多种对象。