Factory Method——工厂方法模式

什么是工厂方法模式

  1. 用模板方法模式来构建生成示例的工厂,就是工厂方法模式。在Factory Method模式中,父类决定实例的生成方式,但并不决定所要生成的具体的类,具体的处理全部交给子类负责。这样就可以将生成示例的框架和实际负责生成示例的类解耦。

工厂方法模式中的角色构成

工厂方法模式的类图

  • Product(产品)
    Product角色属于框架方,是一个抽象类或接口,定义了工厂方法创建的对象。
  • ConcreteCreator(具体的产品)
    1. ConcreteProduct角色属于具体加工这一方,它决定了具体的产品。
  • Creator(创建者)
    1. Creator属于框架方,是一个抽象类,负责生成Product角色,具体处理交由子类ConcreteCreator角色决定。<br />
    2. Creator会声明工厂方法,该方法会生成具体实例并将结果以Product类型的对象返回,可以用工厂方法创建一个Product对象。
  • ConcreteCreator(具体的创建者)
    1. ConcreteCreator角色属于具体加工这一方,它负责生成具体的产品。

示例程序

类组成表

包名 类名 说明
factorymethod.framework Product 只定义了抽象方法use()的抽象类
factorymethod.framework Factory 实现了create方法的抽象类,还包含createProduct()和registerProduct()两个抽象方法
factorymethod.idcard IDCard Product的子类,实现了use()方法
factorymethod.idcard IDCardFactory Factory的子类,实现了createProduct()和registerProduct方法
factorymethod FactoryMain 测试类

示例程序类图:

FactoryMethod模式实例程序类图

Product类:
  1. 属于框架方,位于framework包中,声明了use()方法,定义了产品。
  1. package com.example.factorymethod.framework;
  2. public abstract class Product {
  3. public abstract void use();
  4. }

Factory类:
  1. 属于框架方,位于framework包中,使用了Template Method(模板方法模式)。Factory类声明了生成Product实例的create()方法,以及createProduct()和registerProduct()抽象方法,两个抽象方法的具体处理实现交给Factory类的子类负责。<br />
  2. Factory类定义了工厂是用来“调用create()方法生成Product示例”的。create()方法的实现是先调用createProduct()生成产品,接着调用registerProduct()注册产品。在使用Factory Method模式生成实例时,一定会用到Template Method模式。
  1. package com.example.factorymethod.framework;
  2. public abstract class Factory{
  3. public final Product create(String owner) {
  4. Product product = createProduct(owner);
  5. registerProduct(product);
  6. return product;
  7. }
  8. protected abstract Product createProduct(String owner);
  9. protected abstract void registerProduct(Product product);
  10. }

IDCard类:
  1. 是产品Product的子类
  1. package com.example.factorymethod.idcard;
  2. import com.example.factorymethod.framework.Product;
  3. public class IDCard extends Product {
  4. private String owner;
  5. /*
  6. * IDCard类的构造函数访问修饰符为default,使得idcard包外的类无法new出IDCard类的实例
  7. * 这样可以强迫外部必须通过IDCardFactory来生成IDCard的实例
  8. * */
  9. IDCard(String owner) {
  10. System.out.println("制作" + owner + "的ID卡");
  11. this.owner = owner;
  12. }
  13. @Override
  14. public void use() {
  15. System.out.println("使用" + owner + "的ID卡");
  16. }
  17. public String getOwner() {
  18. return owner;
  19. }
  20. }

IDCardFactory类:
  1. Factory类的子类,实现了createProduct()方法和registerProduct()方法。createProduct()方法通过生成IDCard的实例来实现“生产产品”的操作。registerProduct()方法通过将IDCardowner保存到owners字段中来实现“注册产品”的操作
  1. package com.example.factorymethod.idcard;
  2. import com.example.factorymethod.framework.Factory;
  3. import com.example.factorymethod.framework.Product;
  4. import java.util.ArrayList;
  5. import java.util.List;
  6. public class IDCardFactory extends Factory {
  7. private List owners = new ArrayList();
  8. @Override
  9. protected Product createProduct(String owner) {
  10. return new IDCard(owner);
  11. }
  12. @Override
  13. protected void registerProduct(Product product) {
  14. owners.add(((IDCard)product).getOwner());
  15. }
  16. public List getOwners() {
  17. return owners;
  18. }
  19. }

FactoryMain类:
  1. 测试类,使用FactoryProduct来制作IDCard
  1. package com.example.factorymethod;
  2. import com.example.factorymethod.framework.Factory;
  3. import com.example.factorymethod.framework.Product;
  4. import com.example.factorymethod.idcard.IDCardFactory;
  5. public class FactoryMain {
  6. public static void main(String[] args) {
  7. Factory factory = new IDCardFactory();
  8. Product card1 = factory.create("张三");
  9. Product card2 = factory.create("李四");
  10. Product card3 = factory.create("王五");
  11. card1.use();
  12. card2.use();
  13. card3.use();
  14. }
  15. }

执行结果:
  1. 制作张三的ID
  2. 制作李四的ID
  3. 制作王五的ID
  4. 使用张三的ID
  5. 使用李四的ID
  6. 使用王五的ID

拓展延伸

生成更多的工厂和产品

  1. 通过继承framework包中的Factroy类和Product类,可以创建更多的“工厂”和“产品”,在这个过程中是使用已有的框架生成全新的类,不需要对framework进行修改。

方法的三种实现方式

指定为抽象方法
  1. 将方法指定为抽象方法后,可以交由子类来具体实现。
  1. abstract class Factory {
  2. public abstract Product createProduct(String name);
  3. ......
  4. }

实现默认处理
  1. 实现默认处理后,如果子类没有实现该方法,将执行该方法内的默认处理。
  1. class Factory {
  2. public Product createProduct(String name) {
  3. return new Product(name);
  4. }
  5. ......
  6. }

抛出异常
  1. 在方法中抛出异常,如果未在子类中实现该方法,程序报错。
  1. class Factory {
  2. public Product createProduct(String name) {
  3. //自定义异常,需额外编写FactoryMethodRuntimeException异常类
  4. throw new FactoryMethodRuntimeException();
  5. }
  6. ......
  7. }