java基础——简单工厂模式

简单工厂模式:又叫做静态工厂方法模式,是由一个工厂对象决定创建出哪一种产品类的实例。

简单工厂模式UML图

java基础——简单工厂模式

Client:客户端,调用工厂类的createProduct()方法来创建产品实例。

Factory:工厂类,它负责实现创建所有实例的内部逻辑。工厂类的创建产品类的方法createProduct()可以被外界直接调用,创建所需的产品对象。

Product:抽象的产品类。

ProductA,ProductB:具体的产品实现类。

简单工厂模式简单实现

有卖披萨的,有卖肉夹馍的,还有生产电脑的,这里还是卖披萨吧。假如你有一个披萨店卖披萨。客户点披萨的时候可能代码会是这样。

 public Pizza orderPizza() {
                 //现在只有一种披萨类型
        Pizza pizza = new Pizza();
        pizza.prepare();
        pizza.bake();
        pizza.cut();
        pizza.box();
        return pizza;
    }

当随着时间的推移,你可能会增加几种类型的披萨,这时候,客户点披萨的代码可能就变成下面这样了。

 public Pizza orderPizza(String type) {
       Pizza pizza ;
       if (type.equals("cheese")){
           pizza=new CheesePizza();
       }else if (type.equals("greek")){
           pizza=new GreekPizza();
       }else if (type.equals("pepperoni")){
           pizza=new PepperoniPizza();
       }
       pizza.prepare();
       pizza.bake();
       pizza.cut();
       pizza.box();
       return pizza;
   }

然后随着时间的推移,你又增加了几种不同类型的披萨,同时又得把销售量不好的披萨果断从菜单中去掉。然后点披萨的代码又变了。

public Pizza orderPizza(String type) {
        Pizza pizza;
        if (type.equals("cheese")) {
            pizza = new CheesePizza();
        } else if (type.equals("pepperoni")) {
            pizza = new PepperoniPizza();
        } else if (type.equals("clam")) {
            pizza = new ClamPizza();
        } else if (type.equals("veggie")) {
            pizza = new VeggiePizza();
        }
        pizza.prepare();
        pizza.bake();
        pizza.cut();
        pizza.box();
        return pizza;
    }

很明显,当披萨类型改变的时候,点披萨的逻辑就得修改,来根据类型,创建具体的披萨。orderPizza( )方法无法对修改关闭。最好是能够将创建披萨的逻辑移到orderPizza方法之外。就是说由另外一个对象专职来创建披萨。我们称这个对象为工厂,来处理创建对象的细节(客户,这里就是PizzaStore,并不关心),当需要披萨的时候,就让工厂来做一个披萨。

建立一个简单的披萨工厂

public class SimplePizzaFactory {

    public Pizza createPizza(String type) {
        Pizza pizza = null;
        if (type.equals("cheese")) {
            pizza = new CheesePizza();
        } else if (type.equals("pepperoni")) {
            pizza = new PepperoniPizza();
        } else if (type.equals("clam")) {
            pizza = new ClamPizza();
        } else if (type.equals("veggie")) {
            pizza = new VeggiePizza();
        }
        return pizza;
    }
}

把创建披萨的代码包装进SimplePizzaFactory ,当以后实现改变时,只需修改这个类即可。

现在我们的披萨店的代码也要变了。

public class PizzaStore {

    private SimplePizzaFactory factory;

    public PizzaStore(SimplePizzaFactory factory) {
        this.factory = factory;
    }

    public Pizza orderPozza(String type) {
            //工厂负责处理创建对象的细节
        Pizza pizza = factory.createPizza(type);
        pizza.prepare();
        pizza.bake();
        pizza.cut();
        pizza.box();
        return pizza;
    }
}

在上面的实现中,可以把Pizza定义成一个抽象类,其他的披萨类继承Pizza类。

public  abstract class Pizza {

    protected void prepare() {

    }

    protected void bake() {

    }

    protected void cut() {

    }

    protected void box() {

    }

}

具体的产品实现类

public class ClamPizza extends Pizza {
    
}


public class PepperoniPizza extends Pizza {
    
}

使用简单工厂模式的场景:

  1. 工厂类负责创建的对象比较少。
  2. 客户只知道传入工厂类的参数,对于如何创建对象(逻辑)不关心。

简单工厂模式优点

使用户根据参数获得对应的类实例,避免了直接实例化类,降低了耦合性。

简单工厂模式缺点

可实例化的类型在编译期间已经被确定,如果增加新类型,则需要修改工厂,违背了开放封闭原则(ASD) 。 简单工厂需要知道所有要生成的类型,当子类过多或者子类层次过多时不适合使用。

参考链接: