Factory Method——工厂方法模式
什么是工厂方法模式
用模板方法模式来构建生成示例的工厂,就是工厂方法模式。在Factory Method模式中,父类决定实例的生成方式,但并不决定所要生成的具体的类,具体的处理全部交给子类负责。这样就可以将生成示例的框架和实际负责生成示例的类解耦。
工厂方法模式中的角色构成
工厂方法模式的类图
- Product(产品)
Product角色属于框架方,是一个抽象类或接口,定义了工厂方法创建的对象。 - ConcreteCreator(具体的产品)
ConcreteProduct角色属于具体加工这一方,它决定了具体的产品。
- Creator(创建者)
Creator属于框架方,是一个抽象类,负责生成Product角色,具体处理交由子类ConcreteCreator角色决定。<br />Creator会声明工厂方法,该方法会生成具体实例并将结果以Product类型的对象返回,可以用工厂方法创建一个Product对象。
- ConcreteCreator(具体的创建者)
ConcreteCreator角色属于具体加工这一方,它负责生成具体的产品。
示例程序
类组成表
| 包名 | 类名 | 说明 |
|---|---|---|
| factorymethod.framework | Product | 只定义了抽象方法use()的抽象类 |
| factorymethod.framework | Factory | 实现了create方法的抽象类,还包含createProduct()和registerProduct()两个抽象方法 |
| factorymethod.idcard | IDCard | Product的子类,实现了use()方法 |
| factorymethod.idcard | IDCardFactory | Factory的子类,实现了createProduct()和registerProduct方法 |
| factorymethod | FactoryMain | 测试类 |
示例程序类图:

Product类:
属于框架方,位于framework包中,声明了use()方法,定义了产品。
package com.example.factorymethod.framework;public abstract class Product {public abstract void use();}
Factory类:
属于框架方,位于framework包中,使用了Template Method(模板方法模式)。Factory类声明了生成Product实例的create()方法,以及createProduct()和registerProduct()抽象方法,两个抽象方法的具体处理实现交给Factory类的子类负责。<br />Factory类定义了工厂是用来“调用create()方法生成Product示例”的。create()方法的实现是先调用createProduct()生成产品,接着调用registerProduct()注册产品。在使用Factory Method模式生成实例时,一定会用到Template Method模式。
package com.example.factorymethod.framework;public abstract class Factory{public final Product create(String owner) {Product product = createProduct(owner);registerProduct(product);return product;}protected abstract Product createProduct(String owner);protected abstract void registerProduct(Product product);}
IDCard类:
是产品Product的子类
package com.example.factorymethod.idcard;import com.example.factorymethod.framework.Product;public class IDCard extends Product {private String owner;/** IDCard类的构造函数访问修饰符为default,使得idcard包外的类无法new出IDCard类的实例* 这样可以强迫外部必须通过IDCardFactory来生成IDCard的实例* */IDCard(String owner) {System.out.println("制作" + owner + "的ID卡");this.owner = owner;}@Overridepublic void use() {System.out.println("使用" + owner + "的ID卡");}public String getOwner() {return owner;}}
IDCardFactory类:
Factory类的子类,实现了createProduct()方法和registerProduct()方法。createProduct()方法通过生成IDCard的实例来实现“生产产品”的操作。registerProduct()方法通过将IDCard的owner保存到owners字段中来实现“注册产品”的操作
package com.example.factorymethod.idcard;import com.example.factorymethod.framework.Factory;import com.example.factorymethod.framework.Product;import java.util.ArrayList;import java.util.List;public class IDCardFactory extends Factory {private List owners = new ArrayList();@Overrideprotected Product createProduct(String owner) {return new IDCard(owner);}@Overrideprotected void registerProduct(Product product) {owners.add(((IDCard)product).getOwner());}public List getOwners() {return owners;}}
FactoryMain类:
测试类,使用Factory和Product来制作IDCard。
package com.example.factorymethod;import com.example.factorymethod.framework.Factory;import com.example.factorymethod.framework.Product;import com.example.factorymethod.idcard.IDCardFactory;public class FactoryMain {public static void main(String[] args) {Factory factory = new IDCardFactory();Product card1 = factory.create("张三");Product card2 = factory.create("李四");Product card3 = factory.create("王五");card1.use();card2.use();card3.use();}}
执行结果:
制作张三的ID卡制作李四的ID卡制作王五的ID卡使用张三的ID卡使用李四的ID卡使用王五的ID卡
拓展延伸
生成更多的工厂和产品
通过继承framework包中的Factroy类和Product类,可以创建更多的“工厂”和“产品”,在这个过程中是使用已有的框架生成全新的类,不需要对framework进行修改。
方法的三种实现方式
指定为抽象方法
将方法指定为抽象方法后,可以交由子类来具体实现。
abstract class Factory {public abstract Product createProduct(String name);......}
实现默认处理
实现默认处理后,如果子类没有实现该方法,将执行该方法内的默认处理。
class Factory {public Product createProduct(String name) {return new Product(name);}......}
抛出异常
在方法中抛出异常,如果未在子类中实现该方法,程序报错。
class Factory {public Product createProduct(String name) {//自定义异常,需额外编写FactoryMethodRuntimeException异常类throw new FactoryMethodRuntimeException();}......}
