转自:《Java 设计模式》2009年( 耿祥义 张跃平 著)
一,概括:
工厂方法模式(别名:虚拟构造)
定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method 使一个类的实例化延迟到其子类。
二,引入
得到一个类的子类的实例最常用的办法使使用 new 运算符和 该子类的构造方法,但是在通常情况下系统不允许用户代码和该类的子类形成耦合或者用户不知道该类有哪些子类可用,比如有一个 抽象的 Car类,该类有两个子类 ,Porsche类 和 QQCar类,而系统希望用户用 Factory类的子类的实例 来得到 Car类 的子类的实例。
为此,在设计 Factory类 时,决定让它依赖于 Car类,并且提供了一个返回 Car对象的 方法,比如:public Car createCar();
但是,Factory类 本身并不知道用户需要哪种车,即不知道需要 Car类 的哪个子类的实例,因此需要将 createCae()方法 设置为 抽象方法,自然而然的 Factory类 也要为抽象类,这样我们就可以让其子类重写 createCar()方法,分别返回 Porsche类 和 QQCar类 的实例。于是,当用户需要 porsche类 的实例时,就不必使用 new运算符 和 Porsche类 的构造方法来创建对象,可以使用 Factory1类 创建一个对象,让该对象调用 createCar()方法 就可以为用户获得一个 Porsche类 的实例。
当系统准备为用户提供某个类的子类实例,又不想让用户代码和该子类形成耦合时,就可以使用该工厂方法模式来设计。
工厂方法模式的关键是 在一个接口或抽象类中定义一个 抽象方法,该方法返回某个类的子类的实例,该抽象类或接口 让其 子类或实现该接口 的类 通过重写这个抽象方法 返回某个子类的实例。
三,代码与类图
上述例子的代码:
package MM; abstract class Car { abstract public String getName(); abstract public void buyCar(); } class Porsche extends Car { public String getName() { return "porsche"; } public void buyCar() { System.out.printf("君 可 愿 尝 试 一 下 单 手 开 " + getName() + "!\n"); } } class QQCar extends Car { public String getName() { return "QQcar"; } public void buyCar() { System.out.printf("君 可 愿 尝 试 一 下 单 手 开 " + getName() + "!\n"); } } abstract class Factory { /* 每个 子类构造方法的第一条语句都是隐含地调用 super() 本来来说,如果在这个类中调用 Factory(),那么 createCar().getName() 就会出错, 但是抽象类是无法定义抽象类对象的,也就是说 new Factory() 这一句是不会出现的 所以,这个构造函数只会被子类调用,届时,createCar() 就被重载了,createCar().getName() 就正确了 */ public Factory() { System.out.printf("我们生产了一辆 " + createCar().getName() + ".\n"); } abstract public Car createCar(); } class Factory1 extends Factory { public Car createCar() { return new Porsche(); } } class Factory2 extends Factory { public Car createCar() { return new QQCar(); } } public class M { public static void main(String args[]) { Car c; Factory f; f = new Factory1(); c = f.createCar(); c.buyCar(); f = new Factory2(); c = f.createCar(); c.buyCar(); } }
类图:
(注: 由于找不到合适的箭头,这箭头就画的不标准了)
四,工厂方法模式的结构
① 抽象产品(Product): Car类
② 具体产品(ConcreteProduct): Porsche类 和 QQCar类
③ 构造者(Creator): Factory类
④ 具体构造者(ConcreteCreator): Factory1类 和 Factory2类
============ =========== ========= ========= ========= ====== ===== === == =
思帝乡·春日游 唐代: 韦庄
春日游,杏花吹满头。陌上谁家年少,足风流?
妾拟将身嫁与,一生休。纵被无情弃,不能羞。