欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

工厂方法模式(Factory Method Pattern)

程序员文章站 2022-06-15 11:46:38
...

将实例的生成交给子类

1.基本介绍

模板设计模式中,父类规定处理的流程,在子类中实现具体处理,如果该模式用于生成实例对象,它就演变为工厂设计模式。

工厂方法模式中:父类决定实例的生成方式,但并不决定所要生成具体的类,具体的处理全部交给子类负责。 这样就可以将生成实例的框架和负责生成实例的类解耦。

2.实现过程

类的一览表

名字 说明
Product 只定义抽象方法 use 的抽象类
Factory 实现了create方法的抽象类
IDcard 实现了use方法的类
IDcardFactory 实现了createProduct registerProduct方法的类
Main 测试类

类图
工厂方法模式(Factory Method Pattern)
Product

声明use的抽象方法,交给子类实现,此框架定义了产品是任何可以使用的东西。

/**
 * @author Jay
 * @date 2019/5/21 22:06
 * @description 表示产品的抽象类
 */
public abstract class Product {
    /**
     * 表示产品都有可以被使用的属性
     */
    public abstract void use();
}

Factory

使用模板设计模式,声明了生成产品和注册产品俩个抽象方法,交给子类具体实现,同时定义了实例的具体生成方式。

工厂方法模式在生成实例时一定会用到模板模式的。

/**
 * @author Jay
 * @date 2019/5/21 22:14
 * @description 工厂抽象类
 */
public abstract class Factory {
    /**
     * 用到模板设计模式
     * final修饰生成对象,无法被子类继承,其中规定了生成实例方式.
     */
    public final Product create(String owner) {
        Product p = createProduct(owner);
        registerProduct(p);
        return p;
    }

    /**
     * 注册产品方法
     *
     * @param p
     */
    public abstract void registerProduct(Product p);

    /**
     * 创建产品方法
     *
     * @param owner
     * @return
     */
    protected abstract Product createProduct(String owner);

}

IDCard

产品的具体实现类,定义了产品的实例生成方式,以及 use() 的具体实现,并且构造方法为包级别访问,外界无法直接调用。

/**
 * @author Jay
 * @date 2019/5/21 22:27
 * @description 具体产品实现类
 */
public class IDCard extends Product {
    private String owner;

    /**
     * 默认访问权限,只能本包调用
     */
    IDCard(String owner) {
        System.out.println("制作" + owner + "的ID卡");
        this.owner = owner;
    }

    @Override
    public void use() {
        System.out.println("使用" + owner + "的ID卡");
    }

    public String getOwner() {
        return owner;
    }
}

IDCardFactory

实现了父类的抽象方法,并按照父类的流程具体实现产品的实例化。

/**
 * @author Jay
 * @date 2019/5/21 22:34
 * @description
 */
public class IDCardFactory extends Factory {
    private List owners = new ArrayList<String>();

    @Override
    public void registerProduct(Product p) {
        owners.add(((IDCard) p).getOwner());
    }

    /**
     * 修饰符为类访问,外界无法直接通过创建对象,只能父类接收,调用父类创造类的模板
     *
     * @param owner
     * @return
     */
    @Override
    protected Product createProduct(String owner) {
        //构造方法为包级别,只能本包使用,所以只能通过本类调用
        return new IDCard(owner);
    }
}

Main

/**
 * @author Jay
 * @date 2019/5/21 22:38
 * @description 测试类
 */
public class Main {
    public static void main(String[] args) {
        //父类接收子类实例,可以直接调用父类方法,里氏替换.
        Factory factory = new IDCardFactory();
        Product card1 = factory.create("张三");
        Product card2 = factory.create("李四");
        Product card3 = factory.create("王五");
        //IDCardFactory idCardFactory = new IDCardFactory();
        //idCardFactory.create("赵六"); 由于方法为类访问权限,所以外界无法直接调用
        card1.use();                     //只能用父类去接收,调用父类create方法,然后从内部自动调用.
        card2.use();
    }
}
制作张三的ID卡
制作李四的ID卡
制作王五的ID卡
使用张三的ID卡
使用李四的ID卡
使用王五的ID卡

3.工厂模式中的各种角色

类图:
工厂方法模式(Factory Method Pattern)

Product(产品)

属于框架一方,是一个抽象类,定义了模式中工厂模式中生成的实例所持有的接口,但具体的处理由子类ConcreteProduct角色实现。

Creator(创建者)

属于框架一方,负责生成Product角色的抽象类,但是具体实现由子类实现,只定义了实现的流程.他对负责实际生成实例的ConcteteCreator一无所知,只知道只要调用Product角色和生成实例的方法,就可以生成Product的实例.

不用new关键字来生成实例,而是调用生成实例的专门方法来生成实例,防止父类与其他类的耦合。

ConcreteProduct(具体产品)

属于具体加工这一方,实现父类方法,决定了具体的产品.构造方法为包级别访问,只能本包调用。

ConcteteCreator(具体创建者)

负责生成具体产品,调用专门的生成实例方法来生成产品。


4.思路

框架与具体加工

若上边例子想要创建电视对象,我们只需俩个类继承实现父类方法,并不需要修改框架包中的内容,即框架完全不依赖于具体加工内容.

生成实例的三种实现方式

  • 指定为抽象方法
  • 实现默认处理:直接new出Product类,此时该类无法设置为抽象类.
  • 在其中抛出异常:若没有实现直接抛出异常.

To GitHub