简单工厂模式

172 阅读3分钟

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

提出问题

在实际编码中,我们经常需要选择地 new 出多个对象,就像是零售店在售卖产品时,总是需要根据用户的临时选择来提供不同的商品对象:

class Store {    
    Product order(type) {
        Product production;
        if(isMilk) {
   			production = new Milk();          
        } else if(isBread) {
            production = new Bread();
        }
        return production;
    }
}

使用 new 是没有问题的,问题总是出现在改变的时候,一旦零售店增添了或者删减了新的产品,由于有大量实例化具体类,就必须对它本身代码做出修改。在理想情况下,我们的代码应该是对修改关闭而对扩展开放的。这样当商品发生改变时,零售店本身不需要发生改变,这时候我们考虑将变化的部分抽取出来并使用多态。

简单工厂模式

Pizza店的改进

参考 Head Firse 设计模式 首先假设我们有一个 Pizza 的零售店,售卖各种不同种类的 Pizza,为了把变化的部分剥离出来,我们可以假想一个生产 Pizza 的工厂,根据我们的订单为我们返回不同种类的 Pizza,在零售店中我们使用多态来完成调用。

/**	
	* 首先实现一个Piiza的抽象类
	* 包含Pizza的种类名字和对已完成的pizza的操作
*/
abstract class Pizza {
    String name;

    void brake() {
        System.out.println("brake");
    }
    void cut() {
        System.out.println("cut");
    }
    void box() {
        System.out.println("box");
    }
}

然后我们由抽象类派生一些具体的 Pizza 类

class CheesePizza extends Pizza {
    CheesePizza() {
        name = "cheesePizza";
    }
}

class PepperoniPizza extends Pizza {
    PepperoniPizza() {
        name = "PepperoniPizza";
    }
}

然后我们制定一个生产 Pizza 的简单工厂,用来根据需要 new 出不同的对象

class SimplePizzaFactory {
    static Pizza createPizza(String type) {
        Pizza pizza = null;
        if(type.equals("cheese")) {
            System.out.println("creating CheesePizza");
            pizza = new CheesePizza();
        }else if(type.equals("pepperoniPizza")) {
            System.out.println("creating PepperoniPizza");
            pizza = new PepperoniPizza();
        }
        return pizza;
    }
}

接下来就可以实现这个 Pizza 零售店

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

        pizza.brake();
        pizza.cut();
        pizza.box();

        return pizza;
    }
}

在简单工厂中,我们可以把 Factory 的 create 方法声明为静态方法,这样在我们调用时就不需要实例化 Factory 的对象直接用用类调用 create 方法来得到实例化的子类对象。

下面我们进行测试

public class SimpleFactoryTest {
    public static void main(String[] args) {
        PizzaStore pizzaStore = new PizzaStore();

        Pizza pizza = pizzaStore.orderPizza("cheese");
        System.out.println(pizza.name);
    }
}

得到最终结果

简单工厂模式又称静态工厂模式,作为一种创建模式,简单工厂将不同子类的实例化给剥离出来,专门定义一个类负责创建其他类的实例,我们只需要知道不同子类中的一个参数,然后利用参数对基类进行调用就可以得到不同的子类,被创建的子类有着相同的父类。

模式结构


Factory:用来得到实例化子类对象的工厂

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

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

模式分析

优点

通过工厂模式将对象的创建和对象本身的业务处理分开,这样降低了系统的耦合度,同时关闭了修改,开放了扩展。客户端只需要知道具体产品对应的参数,无需知道类名和创建它的方法,实现了责任个分割,有专门的工厂类为他提供需要的对象实例。

缺点

使所有的操作集中在 Factory 上,但是这样使得 Factory 的职责过重,所有创建子类的逻辑分析都由 Factory 负担。在修改产品类型时必须对 Factory 进行修改,当产品类型较多时,不易于维护

简单工厂模式应用情况

  • 在客户端不需要知道得到类的全部情况,只需要知道对应参数时
  • 在需要创建的子类不多,工厂中逻辑业务不会过度复杂时