工厂模式:抽象工厂

接着上一篇说过的工厂方法,这节来谈一谈抽象工厂:

首先来看一个设计原则

依赖倒置原则:要依赖抽象,不要依赖具体类。不能让高层组件依赖低层组件,而且,不管高层或低层组件,“两者”都应该依赖于抽象。

再回到比萨店:

使用工厂方法后,各地的比萨加盟店生意火爆,但也有些加盟店使用劣质原料,导致信誉下降。

现在我们要创建一个工厂来生产原料,这个工厂负责创建原料家族中的每一种原料。

先来为原料工厂定义一个接口

public interface PizzaIngredientFactory{
  public Dough createDough();
  public Sauce createSauce();
  public Cheese createCheese();
  public veggies[] createVeggiees();
  public Pepperoni createPepperoni();
  public Clams createClam();
}

 接下来要做的是为每一个区域建立一个原料工厂

1,实现PizzaIngredientFactory接口。

2,实现一组原料供工厂使用,例如RedPeppers、ThickCrustDough,每个区域的原料都略有差异。

3,将这一切组织起来,将新的原料工厂整合进旧的PizzaStore中。

让我们来看看纽约原料工厂是怎么实现的

public class NYPizzaIngredientFactory implements PizzaIngredientFactory{
  public Dough createDough(){
    return new ThinCrustDough();
  }
  public Sauce createSauce(){
    return new MarinaraSauce();
  }
  public Veggies[] createVeggies(){
     Veggies veggies[] = {new Garlic(),new Onion(),new Mushroom()};
     return veggies;
  }
  public Pepproni createPepperoni(){
     return new SlicedPepperoni();
  }
  pubilc Clams createClam(){
     return new FreshClams();
  }
}

定义Pizza基类,由子类实现prepare方法

package com.headfirst.chapter4;

import java.util.ArrayList;
import java.util.List;

public abstract class Pizza {
	String name;
	String dough;
	String sauce;
	Veggies veggies[];
	Cheese cheese;
	Pepperoni pepperoni;
	Clam clam;
	abstract void prepare();
	
	void bake(){
		System.out.println("Bake for 25 minutes at 350 ");
	}
	void cut(){
		System.out.println("Cutting the pizza into diagonal slices ");
	}
	void box(){
		System.out.println("Place pizza in offical PizzaStore box");
		System.out.println();
	}
	public String getName(){
		return name;
	}
}

我们来实现一个CheesePizza类,它继承Pizza基类

NYCheesePizza和ChicagoCheesePizzao类相似,唯一的不同是使用区域性的原料。比萨的做法都一样。

public class CheesePizza(){
  PizzaIngredientFacotry ingredientFactory;
  public CheesePizza(PizzaIngredientFactory ingredientFactory){
    this.ingredientFactory = ingredientFactory;
  }
  void prepare(){
     System.out.println("Prepareing "+name);
     dough = ingredientFactory.createDough();
     sauce = ingredientFactory.createSauce();
     cheese = ingredientFactory.createCheese();
  }
}

也来看看ClamPizza(蛤蜊比萨)

public class ClamPizza(){
  PizzaIngredientFacotry ingredientFactory;
  public CheesePizza(PizzaIngredientFactory ingredientFactory){
    this.ingredientFactory = ingredientFactory;
  }
  void prepare(){
     System.out.println("Prepareing "+name);
     dough = ingredientFactory.createDough();
     sauce = ingredientFactory.createSauce();
     cheese = ingredientFactory.createCheese();
     clam = ingredientFactory.createClam();
  }
}

再回到比萨店,在纽约比萨店里使用纽约原料工厂。

pubic class NYPizzaStore extends PizzaStore{
  public Pizza createPizza(String item){
     PizzaIngredientFactory factory = new NYPizzaIngredientFactory();
     Pizza pizza = null;
     if(item.equals("cheese")){
       pizza = new CheesePizza(factory);
     }else if(item.equals("clam")){
        pizza = new ClamPizza(factory);
     }
     return pizza;
  }
}

  

 抽象工厂的定义:

提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。

 

工厂方法与抽象工厂的区别:

两个工厂都是负责创建对象,工厂方法是使用继承抽象方法,这意味着利用工厂方法创建对象,需要扩展一个类,并覆盖它的工厂方法。

抽象工厂负责创建一个产吕家族的抽象类型,这个类型的子类定义了产品被产生的方法。要想使用这个工厂必须先实例化它。然后将它传入

一些针对抽象类型所写的代码中。

它们两个的区别是:抽象工厂需要一个大的接口,因为它是用来创建整个产品家族的(比如,从多原料,每个原料都是一个对象,那么一次就要生产多个对象),

而工厂方法只是创建一个产品,所以根本不需要一个大的接口,只需要一个方法就可以了。

抽象工厂的具体工厂一般使用工厂方法来创建它们的产品,

猜你喜欢

转载自mynote.iteye.com/blog/1538772