工厂方法模式

81 阅读3分钟

这是我参与11月更文挑战的第9天,活动详情查看:2021最后一次更文挑战

连锁Pizza店的问题

简单工厂更适合被看成一个编程习惯,工厂方法模式具有着超越静态工厂模式的优点,由抽象类定义生产方法,然后由具体类去实现,对于简单工厂来说,这样的模式使得有多个不同的工厂提供有细微差别的同类产品, 将 factory 这个基类可以派生出多个子类来提供对象,更加符合开闭原则。假设我们的 PizzaStore 开成了连锁店,那么会有产生各种地域风格的店,我们不能把 Pizza 的产生都放在 Store 中,我们需要将功能放到他们不同的子类中,相当于将简单工厂中的大工厂进行分解。这里我们可以用到工厂方法模式。

对 Pizza 类及其子类的实现与简单工厂模式相同。

对 PizzaStore 定义,这里我们不再需要显式的 Pizza 工厂,因为将对象的实例化转移到 PizzaStore 的子类中。

abstract class PizzaStore {
    Pizza orderPizza(String type) {
        Pizza pizza = createPizza(type);

        pizza.bake();
        pizza.cut();
        pizza.box();

        return pizza;
    }

    abstract Pizza createPizza(String type);
}

PizzaStore 的子类,由子类控制Pizza实例对象的生成

class NewYorkPizzaStore extends PizzaStore {
    @Override
    Pizza createPizza(String type) {
        Pizza pizza = null;
        if(type.equals("cheese")) {
            System.out.println("NewYorkCheese");
            pizza = new NewYorkCheesePizza();
        }
        return pizza;
    }
}

class ChicagoPizzaStore extends PizzaStore {
    @Override
    Pizza createPizza(String type) {
        Pizza pizza = null;
        if(type.equals("cheese")) {
            System.out.println("ChicagoCheese");
            pizza = new ChicagoCheesePizza();
        }
        return pizza;
    }
}

进行测试

public class FactoryMethodTest {
    public static void main(String[] args) {
        PizzaStore newYorkPizzaStore = new NewYorkPizzaStore();
        PizzaStore chicagoPizzaStore = new ChicagoPizzaStore();
        Pizza pizza;
        pizza = newYorkPizzaStore.orderPizza("cheese");
        System.out.println("--------next--------");
        pizza = chicagoPizzaStore.orderPizza("cheese");
    }
}

得到最终结果

image.png

我们发现 Store 本身已经不在进行 Pizza 实例对象的产生,而将他交给自己的子类对象来实现 create 方法,这就是工厂方法模式,父类工厂只负责接口,而具体的实现交给工厂子类实现,通过工厂子类觉得要哪一个具体类,这样保有了简单工厂的优点,同时也克服了工厂负担过重的缺点。

模式结构

image.png

Factory:抽象的工厂类,负责对产品共有的一些操作

ConcreteFactory:具体工厂,负责不同大类的产品对象的创建、分担创建对象的工作

Product:抽象产品,所有对象的父类,描述所有对象共有的公共接口

ConcreteProduct:具体的产品,创新对象都是它的实例化

模式分析

工厂方法模式是简单工厂模式的进一步抽象和推广。使用了面向对象的多态性,模式保持了简单工厂模式的优点,而且克服了它的缺点。在工厂方法模式中,核心的工厂类不再负责所有产品的创建,而是将具体创建工作交给子类去做。这个核心类仅仅负责给出具体工厂必须实现的接口,而不负责哪一个产品类被实例化这种细节,这使得工厂方法模式可以允许系统在不修改工厂角色的情况下引进新产品。但由于不同的具体工厂负责不同类的产品的生产,使得我们在增加新产品时需要格外多增加新的具体工厂类。

工厂方法模式的应用情况

与简单工厂模式类似,在客户端需要得到产品时只需要调用抽象工厂,不必知道是哪一个具体工厂实现它的。