理解工厂模式

2018-11-21  本文已影响0人  梦的飞翔_862e
概念理解

工厂模式是一种创建型模式,统一创建对象,供客户端使用。客户端仅需从工厂中取对象,而不用关心创建对象的逻辑。

实例描述

以西餐厅制作披萨为例,西餐厅目前提供披萨种类有cheese pizza,pepper pizza,bacon pizza,点餐系统需要根据客户要求不同,制作不同的pizza。

直接实现:

在不使用任何模式的情况下,类的结构大致是这样的


public abstract class Pizza {

    private String name ;
    public Pizza(String name){
        this.name = name;
    }

    public abstract void  prepare();
    public void bake(){
        System.out.println(name+" is baked");
    }
    public void cut(){
        System.out.println(name+" is cut");
    }
    public void box(){
        System.out.println(name+" is boxed");
    }

    public String getName() {
        return name;
    }
}
public class BaconPizza extends Pizza {

    public BaconPizza(){
        super("baconPizza");
    }

    @Override
    public void prepare() {
        System.out.println(getName()+"is prepared");
    }
}
public class RestaurantClient {
    public void  createPizza(String type){
        Pizza pizza = null;
        if("cheese".equals(type)){
            pizza =  new CheesePizza();
        }else if ("bacon".equals(type)){
            pizza=new  BaconPizza();
        }else if("pepper".equals(type)){
            pizza=new  PepperPizza();
        }

        if(pizza !=null){
            pizza.prepare();
            pizza.bake();
            pizza.cut();
            pizza.box();
        }
    }
}

缺点:这种直接的结构是客户端以if else的方式创建不同类,客户端必须关注类是如何创建的,如果新加入一个新的品种,客户端需要重新改造代码,加入新的品种。这种紧耦合的方式,违背了开放封闭原则。

设计一:简单工厂模式

简单工厂模式仅仅是把变化的部分独立出来,客户端仅需要关注业务,无需关注对象是如何创建的。


public class PizzaFactory {

public static Pizza createPizza(String type){
    Pizza pizza = null;
    if("cheese".equals(type)){
        pizza =  new CheesePizza();
    }else if ("bacon".equals(type)){
        pizza=new BaconPizza();
    }else if("pepper".equals(type)){
        pizza=new PepperPizza();
    }
    return pizza;
}

}

public class RestaurantClient {
    public void  productPizza(String type){
       Pizza pizza = PizzaFactory.createPizza(type);
        if(pizza !=null){
            pizza.prepare();
            pizza.bake();
            pizza.cut();
            pizza.box();
        }
    }
}

优点:将创建对象的功能独立出来,客户端仅需关注业务,无需关注对象的创建逻辑
缺点:工厂类中包含了所有类的创建,违反了高内聚的单一职责原则,不利于扩展。

设计二:工厂方法模式

避免简单工厂模式的缺点,核心工厂抽象为一个接口,将对象实例化交给具体工厂子类,核心工厂仅给出创建必须实现的接口,不再关注对象的具体实例化逻辑。具体工厂各司其职,给出具体的创建对象逻辑。


public interface IPizzaFactory {
    Pizza createPizza();
}
public class BaconPizzaFactory implements IPizzaFactory {
    @Override
    public Pizza createPizza() {
        return new BaconPizza();
    }
}
public class RestaurantClient {
    public void  createPizza(String type){
       IPizzaFactory factory =null;
        if("cheese".equals(type)){
            factory =  new CheesePizzaFactory();
        }else if ("bacon".equals(type)){
            factory=new BaconPizzaFactory();
        }else if("pepper".equals(type)){
            factory=new PepperPizzaFactory();
        }
        Pizza pizza = factory.createPizza();
        if(pizza !=null){
            pizza.prepare();
            pizza.bake();
            pizza.cut();
            pizza.box();
        }
    }
}
设计三

当西餐厅加入了新的产品类别-饮料时,就用到了抽象工厂模式。抽象工厂管理了多个品类的抽象创建方法,同时设计一个工厂构造器来创建具体的工厂。


public interface IFactory {
    Pizza createPizza();
    Drink createDrink();
}
public class BaconFactory implements  IFactory{

    @Override
    public Pizza createPizza() {
        return new BaconPizza();
    }
    @Override
    public Drink createDrink() {
        return new OrangeDrink();
    }
}
public class FactoryCreator {

    public static IFactory createFactory(String type){
        IFactory factory = null;
        if("cheese".equals(type)){
            factory =  new CheeseFactory();
        }else if ("bacon".equals(type)){
            factory=new BaconFactory();
        }else if("pepper".equals(type)){
            factory=new PepperFactory();
        }
        return factory;
    }
}
public class RestaurantClient {
    public void  createPizza(String type){
        IFactory factory =FactoryCreator.createFactory(type);
        Pizza pizza = factory.createPizza();
        if(pizza !=null){
            pizza.prepare();
            pizza.bake();
            pizza.cut();
            pizza.box();
        }
        Drink drink = factory.createDrink();
        if(drink!=null){
            drink.prepare();
            drink.box();
        }
    }
}
注意点

曾经对工厂方法模式和抽象工厂模式的概念理解模糊不清,这里记录一下:
工厂方法模式是抽象工厂模式一个特例。
工厂方法模式适用于单一品类的工厂实例创建,抽象工厂适用于多种品类的工厂实例创建,两种适用场景不同
可以通过反射来构造不同的工厂对象,这样扩展时不要修改工厂构造器,改造后实例如下

   public static IFactory createFactory(Class<? extends IFactory> clazz) throws IllegalAccessException, InstantiationException {
      if(clazz !=null){
          IFactory factory =clazz.newInstance();
          return factory;
      }
      return null;
    }

具体实例参见:https://github.com/jxl198/designPattern/tree/master/factory

上一篇 下一篇

猜你喜欢

热点阅读