工厂模式

工厂模式,
示例,比萨商店,制作各类口味的比萨,纽约风味,芝加哥风味,希腊风味

工厂方法用来处理对象的创建,并将这样的行为封装在子类中,超类的代码就和子类对象创建代码解耦了。

//抽象比萨类
public abstract class Pizza{
  String name;
  String dough;
  String sauce;
  ArrayList toppings = new ArrayList();

  void prepare()
  {
    //...
  }
  void cut()
  {
    //...
  }

  void box()
  {
    //...
  }
}

//具体比萨类
public class NYStyleCheesePizza extends Pizza{
  public NYStyleCheesePizza()
  {
    name = "NYStyle Pizza";
    dough = "Thin dough";
    sauce = "Marinara sauce";
    toppings.add("Grated Reggiano Cheese");
  }
}

//父类
public abstract class PizzaStore{

  public Pizza orderPizza(String type)
  {
    Pizza pizza;
    pizza = createPizza(type);

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

    return pizza;
  }

  //此方法就如同是一个工厂
  protected abstract Pizza createPizza(String type);

}

//子类
public class NYPizzaStore extends PizzaStore{

  protected Pizza createPizza(String type)
  {
    if(type.equals("cheese"))
    {
      return new NYStyleCheesePizza();
    }
    else if(type.equals("veggie"))
    {
      return new NYStyleVeggiePizza();
    }
    else if(type.equals("clam"))
    {
      return new NYStyleClamPizza();
    }
    else if(type.equals("pepperoni"))
    {
      return new NYStylePepperoniPizza();
    }
    else
    {
      return null;
    }
  }

}


定义工厂方法模式:


定义了一个创建对象的接口,但由子类决定要实例化的类是哪一个。工厂方法让类把实例推迟到子类。

依赖倒置原则:
1、变量不可以持有具体类的引用
2、不要让类派生自具体类
3、不要覆盖基类已实现的方法
这个原则说明了:不能让高层组件依赖低层组件,而且不管高层或底层组件,“两者”都应依赖于抽象。

PizzaStore是高层组件,而比萨是低层组件,我们要做到不依赖于比萨的具体实现,而是依赖比萨的抽象。

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

抽象工厂模式:

抽象工厂允许客户使用抽象的接口来创建一组相关的产品,而不需要知道实际产出的具体产品是什么。
这样以来,客户就从具体的产品中被解耦。

开始先为工厂定义一个接口,这个接口负责创建所有的原料:
也可以定义为一个抽象类

public interface PizzaIngredientFactory{
  public Dough createDough();
  public Sauce createSauce();
  public Cheese createCheese();
  public Veggies createVeggies();
  public Pepperoni createPepperoni();
  public Clam createClam();
}


public class NYPizzaIngredientFactory implements PizzaIngredientFactory{
  public Dough createDough()
  {
    return new ThinCrustDough();
  }
  public Dough createSauce()
  {
    return new MarinaraSauce();
  }
  public Dough createCheese()
  {
    return ...;
  }
  public Dough createVeggies()
  {
    return ...;
  }
  public Dough createPepperoni()
  {
    return ...;
  }
  public Dough createClam()
  {
    return ...;
  }
}

//比萨抽象类
public abstract class Pizza{
  String name;
  Dough dough;
  Sauce sauce;
  Veggies veggies[];
  Cheese cheese;
  Pepperoni pepperoni;
  Clams clam;

  abstract void prepare();

  void prepare()
  {
    //...
  }

  void cut()
  {
    //...
  }

  void box()
  {
    //...
  }

}


//比萨具体类
public class CheesePizza extends Pizza{
  PizzaIngredientFactory ingredientFactory;

  public CheesePizza(PizzaIngredientFactory ingredientFactory)
  {
    this.ingredientFactory = ingredientFactory;
  }

  void prepare()
  {
    dough = ingredientFactory.createDough();
    sauce = ingredientFactory.createSauce();
    cheese = ingredientFactory.createCheese();
  }


}

public class NYPizzaStore extends PizzaStore{

  protected Pizza createPizza(String type)
  {
    Pizza pizza = null;

    PizzaIngredientFactory ingredientFactory = new NYPizzaIngredientFactory();

    if(type.equals("cheese"))
    {
      pizza = new CheesePizza(ingredientFactory);

    }
    else if(type.equals("veggie"))
    {
    pizza = new VeggiePizza(ingredientFactory);
    }
    else if(type.equals("clam"))
    {
      pizza = new ClamPizza(ingredientFactory);
    }
    else if(type.equals("pepperoni"))
    {
      pizza = new PepperoniPizza(ingredientFactory);
    }

    return pizza;
  }

}


订购:
PizzaStore nyPizzaStore = new NYPizzaStore();

nyPizzaStore.orderPizza("cheese");

orderPizza()方法首先调用createPizza()方法

Pizza pizza = createPizza("cheese");

Pizza pizza = new CheesePizza(nyIngredientFactory);

 

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

抽象工厂跟工厂方法:

抽象工厂:当你需要创建产品家族和想让制造的相关产品集合起来时,你可以使用我。(通过对象的组合)(把一群相关的产品集合起来)

工厂方法:(利用工厂方法创建对象,需要扩展一个类,并覆盖他的工厂方法,本质是继承)
通过子类来创建对象,用这种方法,客户只需要知道他们所使用的抽象类型就可以了,而由子类来负责决定具体类型。
换句话说,我只负责将客户从具体类型中解耦。
---------------------------------------------------------------------------------------

原文地址:https://www.cnblogs.com/zhangxuan/p/8392286.html