设计模式笔记——工厂模式

《Head first设计模式》中使用比萨做例子,我们这里也都用比萨举例。我们假设要开一家比萨店。

工厂模式产生的压力主要来自于增加更多类型的比萨类。同时避免直接实例化对象,因为我们设计程序时应该面向接口编程。这样会让程序更容易维护和扩展,使其更有弹性。

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

遵守的原则:依赖倒置原则,就是要依赖抽象,不要依赖具体类。这个原则比“针对接口编程”更加“抽象”。这个原则说明了:不能让高层组件依赖低层组件,而且,不管高层组件或低层组件,“两者”都应该依赖于抽象。其中的关系,如下图所示:

设计模式笔记——工厂模式_第1张图片


现在通过结合程序来解释工厂模式。我们需要两个工厂,一个是比萨工厂,另一个是原料工厂。之间的类图关系如下:

设计模式笔记——工厂模式_第2张图片


根据类图分析程序:

一、首先我们需要有三个抽象,Pizza、PizzaStore、PizzaIngredientFactory,它们分别代表比萨、比萨工厂、原料工厂。代码如下:

*
 * 从一个抽象比萨开始,所有的具体比萨都必须派生自这个类。
 */
public abstract class Pizza
{
    String name;
    //每一个比萨都持有一组在准备时会用到的原料
    Dough dough;
    Sauce sauce;
    Veggies veggies[];
    Cheese cheese;
    Pepperoni pepperoni;
    Clams clam;

    /**
     * 把prepare()方法声明成抽象。在这个方法中,我们需要收集比萨所需的原料,
     * 而这些原料当然是来自原料工厂了。
     */
    abstract void prepare();

    public void bake()
    {
        System.out.println("baking");
    }
    public void cut()
    {
        System.out.println("cutting");
    }
    public void box()
    {
        System.out.println("box");
    }

    public void setName(String name)
    {
        this.name=name;
    }
    public String getName()
    {
        return name;
    }
}

*
 * PizzaStore作为超类,让每个域类型(NYPizzaStore)都继承这个
 * PizzaStore,每个子类各自决定如何制造比萨。
 */
public abstract class PizzaStore
{
    /**
     * 每个子类都必须自己实现createPizza方法
     * @param type
     * @return
     */
    protected abstract Pizza createPizza(MenuList type);
}


public interface PizzaIngredientFactory
{
    /**
     * 在接口中,每个原料都有一个对应的方法创建该原料。
     *这里的每一个原料都是一个类。
     */
    public Dough createDough();
    public Sauce createSauce();
    public Cheese createCheese();
    public Veggies[] createVeggies();
    public Pepperoni createPepperoni();
    public Clams createClam();
}

二、有了抽象后我们要分别实现抽象。

public class ClamPizza extends Pizza
{
    PizzaIngredientFactory ingredientFactory;

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

    public void prepare()
    {
        System.out.println("Preparing  "+name);
        dough=ingredientFactory.createDough();
        sauce=ingredientFactory.createSauce();
        cheese=ingredientFactory.createCheese();
        clam=ingredientFactory.createClam();
    }
}

public class NYPizzaStore extends PizzaStore
{
    public Pizza createPizza(MenuList item)
    {
        Pizza pizza=null;

        //纽约店会用纽约比萨原料工厂的原料
        PizzaIngredientFactory ingredientFactory=new NYPizzaIngredientFactory();
        if(item==MenuList.Cheese)
        {
            pizza=new CheesePizza(ingredientFactory);//把工厂传递给每一个比萨,以便比萨能从工厂中取得原料
            pizza.setName("New York Style Cheese Pizza");
        }else if(item==MenuList.Veggie)
        {
            pizza=new VeggiePizza(ingredientFactory);
            pizza.setName("New York Style Veggie Pizza");
        }else if(item==MenuList.Clam)
        {
            pizza=new ClamPizza(ingredientFactory);
            pizza.setName("New York Style Clam Pizza");
        }else if(item==MenuList.Pepperoni)
        {
            pizza=new PepperoniPizza(ingredientFactory);
            pizza.setName("New York Style Pepperoni Pizza");
        }
        if(pizza!=null)
        {
            System.out.println(pizza.getName());
        }
        return pizza;
    }
}


*
 * 具体原料工厂必须实现这个接口。
 */
public class NYPizzaIngredientFactory implements PizzaIngredientFactory
{
    /**
     * 为原料家族中的每一种原料都提供了纽约版本
     */
    public Dough createDough()
    {
        return new ThinCrustDough();
    }
    public Sauce createSauce()
    {
        return new MarinaraSauce();
    }
    public Cheese createCheese()
    {
        return new ReggianoCheese();
    }
    public Veggies[] createVeggies()
    {
        Veggies veggies[]={new Garlic(),new Onion(),new Mushroom(),new RedPepper()};
        return veggies;
    }
    public Pepperoni createPepperoni()
    {
        return new SlicedPepperoni();
    }
    public Clams createClam()
    {
        return new FreshClams();
    }
}


三、主程序调用:

public static void main(String[] args)
    {
        PizzaStore nyStore=new NYPizzaStore();
        Pizza pizza=nyStore.createPizza(MenuList.Cheese);
        Pizza pizzaVeggie=nyStore.createPizza(MenuList.Veggie);
    }



你可能感兴趣的:(设计模式笔记——工厂模式)