在设计模式中,Factory Method也是比较简单的一个,但应用非常广泛,EJB,RMI,COM,CORBA,Swing中都可以看到此模式的影子,它是最重要的模式之一。
作者:中国IT实验室 来源:中国IT实验室 2007年8月26日
关键字:
首先客户端可以统一从抽象创建器获取产生的实例,Creator的作用将client和产品创建过程分离开来,客户不用操心返回的是那一个具体的产品,也不用关心这些产品是如何创建的。
同时,ConcreteProduct也被隐藏在Product后面,ConreteProduct继承了Product的所有属性,并实现了Product中定义的抽象方法,按照Java中的对象造型(cast)原则,通过ConcreteCreator产生的ConcreteProduct可以自动的上溯造型成Product。这样一来,实质内容不同的ConcreteProduct就可以在形式上统一为Product,通过Creator提供给client来访问。
其次,当我们添加一个新的ConcreteCreator时,由于Creator所提供的接口不变,客户端程序不会有丝毫的改动,不会带来动一发而牵全身的灾难, 这就是良好封装性的体现。但如果直接用ConcreteProduct和ConcreteCreator两个类是无论如何也做不到这点的。
优良的面向对象设计鼓励使用封装(encapsulation)和委托(delegation),而Factory Method模式就是使用了封装和委托的典型例子,这里封装是通过抽象创建器Creator来体现的,而委托则是通过抽象创建器把创建对象的责任完全交给具体创建器ConcreteCreator来体现的。
现在,请再回头看看基本概念中的那段话,开始也许觉得生涩难懂,现在是不是已经明朗化了很多。
下面让我们看看在 Java 中如何实现Factory Method模式,进一步加深对它的认识。
具体实施
先说明一点,用Factory Method模式创建对象并不一定会让我们的代码更短,实事上往往更长,我们也使用了更多的类,真正的目的在于这样可以灵活的,有弹性的创建不确定的对象。而且,代码的可重用性提高了,客户端的应用简化了,客户程序的代码会大大减少,变的更具可读性。
标准实现: 这里我采用Bruce Eckel 用来描述OO思想的经典例子 Shape。这样大家会比较熟悉一些。我完全按照图1中所定义的结构写了下面的一段演示代码。这段代码的作用是创建不同的Shape实例,每个实例完成两个操作:draw和erase。具体的创建过程委托?ShapeFactory来完成。
1.a 首先定义一个抽象类Shape,定义两个抽象的方法。
abstract class Shape
{
// 勾画shape
public abstract void draw();
// 擦去 shape
public abstract void erase();
public String name;
public Shape(String aName)
{
name = aName;
}
}
1.b 定义 Shape的两个子类: Circle, Square,实现Shape中定义的抽象方法
// 圆形子类
class Circle extends Shape
{
public void draw()
{
System.out.println("It will draw a circle.");
}
public void erase()
{
System.out.println("It will erase a circle.");
}
// 构造函数
public Circle(String aName)
{
super(aName);
}
}
// 方形子类
class Square extends Shape
{
public void draw()
{
System.out.println("It will draw a square.");
}
public void erase() {
System.out.println("It will erase a square.");
}
// 构造函数
public Square(String aName)
{
super(aName);
}
}