工厂模式
定义
工厂方法模式定义了一个创建对象的接口,但由子类决定(“决定”是指在编写创建者类creator类时,不需要知道实际创建的product是哪一个。选择使用了哪个子类,自然就决定了实际创建的产品是什么)要实例化的类是哪一个。
工厂方法让类把实例化推迟到子类。ConcreteCreator负责创建一个或多个具体产品,只有ConcreteCreator类知道如何创建这些产品(组合使用了ConcreteProduct)。
简单工厂模式是让一个对象负责所有具体类的实例化,而工厂模式是让一群子类(NYStylePizzaStore, ChicagoStylePizzaStore)来负责实例化。工厂方法 createPizza()是抽象的,所以会依赖子类来处理对象的创建 --- 工厂模式通过让子类决定该创建的对象是什么,来达到将对象创建的过程封装的目的。
Creator:
PizzaStore实现:
java
public abstract class PizzaStore { public final Pizza orderPizza(String type) // order system { Pizza pizza; pizza = createPizza(type); pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); return pizza; } abstract Pizza createPizza(String type); // factory method }
java
public class ChicagoPizzaStore extends PizzaStore { Pizza pizza = null; @Override Pizza createPizza(String type) { if(type.equals("cheese")){ pizza = new ChicagoStyleCheesePizza(); // create specific class }else if(type.equals("pepperoni")){ pizza = new NYStylePepperoniPizza(); // create specific class }else if (type.equals("clam")){ pizza = new NYStyleClamPizza(); // create specific class }else if (type.equals("veggie")){ pizza = new NYStyleVeggiePizza(); // create specific class } return pizza; } }
java
public class NYPizzaStore extends PizzaStore { Pizza pizza = null; @Override Pizza createPizza(String type) { if(type.equals("cheese")){ pizza = new NYStyleCheesePizza(); // create specific class }else if(type.equals("pepperoni")){ pizza = new NYStylePepperoniPizza(); // create specific class }else if (type.equals("clam")){ pizza = new NYStyleClamPizza(); // create specific class }else if (type.equals("veggie")){ pizza = new NYStyleVeggiePizza(); // create specific class } return pizza; } }
Products:
Pizza的实现
java
import java.util.*; public abstract class Pizza { String name; String dough; String sauce; ArrayList<String> toppings = new ArrayList<String>(); public void prepare(){ System.out.println("Preparing " + name); System.out.println("Tossing dough"); System.out.println("Adding sauce "); System.out.println("Adding toppings"); for (int i = 0;i<toppings.size();i++){ System.out.println(" " + toppings.get(i)); } } public void bake(){ System.out.println("Bake for 25 mins at 350"); } public void cut(){ System.out.println("Cutting the pizza into diagonal slics"); } public void box(){ System.out.println("Place pizza in official PizzaStore box"); } public String getName(){ return name; } }
java
public class NYStyleCheesePizza extends Pizza{ public NYStyleCheesePizza(){ name = "NY Style Sauce and Cheese Pizza"; dough = "Thin Crust Dough"; sauce = "Marinara Sauce"; toppings.add("Grated Regginao Cheese"); } }
测试类
java
public class PizzaTestDrive { public static void main(String[] args){ // create two stores PizzaStore nyStore = new NYPizzaStore(); PizzaStore chicagoStore = new ChicagoPizzaStore(); Pizza pizza = nyStore.orderPizza("cheese"); System.out.println("Ethan ordered a" + pizza.getName() + "\n"); pizza = chicagoStore.orderPizza("cheese"); System.out.println("Joel ordered a" + pizza.getName() + "\n"); } }
抽象工厂模式
定义
抽象工厂模式提供一个接口,用于创建相关或依赖对象的家族(使用抽象的接口来创建一组相关的产品),而不需要明确指定具体类。
这个接口内的每个方法都负责创建一个具体的产品,同时我们利用实现抽象工厂的子类来提供这些具体的做法。
好处
创建产品家族 + 将相关产品集合起来。
具体实现
AbstractFactory接口创建一个产品家族
java
public interface PizzaIngredientFactory { public Dough createDough(); public Sause createSauce(); public Cheese createCheese(); public Veggies[] createVeggies(); public Pepperoni createPepperoni(); public Clams createClam(); }
具体工厂实现不同的产品家族。
java
public class NYPizzaIngredientFactory implements PizzaIngredientFactory { public Cheese createCheese() { return new ReggianoCheese(); } public Clams createClam() { return new FreshClams(); } public Dough createDough() { return new ThinCrustDough(); } public Pepperoni createPepperoni() { return new SlicedPepperoni(); } public Sause createSauce() { return new MarinaraSauce(); } public Veggies[] createVeggies() { Veggies veggies[] = { new Garlic(), new Onion(),new Mushroom(),new RedPepper() }; return veggies; } }
抽象的产品
Pizza接口
java
public abstract class Pizza { String name; Dough dough; Sause sauce; Veggies veggies[]; Cheese cheese; Pepperoni pepproni; Clams clam; abstract public void prepare(); public void bake(){ System.out.println("Bake for 25 mins at 350"); } public void cut(){ System.out.println("Cutting the pizza into diagonal slics"); } public void box(){ System.out.println("Place pizza in official PizzaStore box"); } public String getName(){ return name; } public void setName(String name){ this.name = name; } }
具体的产品CheesePizza:使用了(组合)抽象工厂生产的一组产品,集合起来的产品为CheesePizza
java
public class CheesePizza extends Pizza { PizzaIngredientFactory ingredientFactory; // 要制作pizza,需要提供原料,所以每个pizza都需要从构造器参数得到一个工厂 public CheesePizza(PizzaIngredientFactory ingredientFactory){ this.ingredientFactory = ingredientFactory; } @Override public void prepare() { System.out.println("Preparing "+name); dough = ingredientFactory.createDough(); sauce = ingredientFactory.createSauce(); cheese = ingredientFactory.createCheese(); } }
客户的代码只需要涉及抽象工厂
java
public class NYPizzaStore extends PizzaStore { Pizza createPizza(String item){ Pizza pizza = null; PizzaIngredientFactory ingredientFactory = new NYPizzaIngredientFactory(); if(item.equals("cheese")) { pizza = new CheesePizza(ingredientFactory); pizza.setName("New York style cheese pizza"); } else if (item.equals("veggie")) { pizza = new VeggiePizza(ingredientFactory); pizza.setName("New York style veggie pizza"); } return pizza; } }
工厂模式 VS 抽象工厂模式
都负责封装对象的创建。都能将对象的创建封装起来,将应用程序解耦,并降低对其特定实现的依赖。
工厂模式使用的是类,通过继承,即利用工厂方法创建对象,需要扩展一个类,并覆盖它的工厂方法。
工厂模式提供一个抽象的接口来创建一个产品,由每个子类决定实例化哪个具体的产品(具体类)
而抽象工厂模式使用的是对象,使用组合。即提供一个用来创建一个产品家族的抽象类型,这个类型的子类定义了产品被产生的方法。要使用这个工厂,必须先实例化它,然后将它传入一些针对抽象类型所写的代码里。
抽象工厂模式提供一个抽象接口来创建一个产品家族,每个具体子类都创建一个家族产品。