工厂方法

设计原则:依赖倒置原则(要依赖抽象,不要依赖具体类)

该设计原则的最佳实践方式的几个指导方针:

1.变量不可以持有具体类的引用。(如果使用new,就会持有具体类的引用,可用工厂来避开这样的做法)

2.不要类派生自具体类。(如果派生自具体类,就会依赖具体类)

3.不要覆盖基类中已实现的方法。(如果覆盖基类已实现的方法,那么你的基类就不是一个真正适合被继承的抽象,基类中实现的方法应该由所有的子类共享)

我们在写代码的时候尽量去追寻这些方针,将这些方针内化成你的设计的一部分(不追求代码之美的自动忽略)。

 

下面回到工厂模式

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

工厂方法的UML图:

 

下面是Head First中关于工厂方法模式的PizzaDemo:

package com.zjut.json.factoryMethod;

import java.util.ArrayList;

/**
 * 披萨类
 * 
 * @author json
 *
 * @date 2013-5-7
 */
public abstract class Pizza {
    
    /**pizza的名字*/
    private String name;
    
    /**pizza的面团类型*/
    private String dough;
    
    /**pizza酱料类型*/
    private String sauce;
    
    /**pizza相关佐料*/
    @SuppressWarnings("rawtypes")
    ArrayList toppings = new ArrayList();
    
    public void prepare(){
        System.out.println("Preparing " + getName());
        System.out.println("Tossing dough...");
        System.out.println("Adding sauce...");
        System.out.println("Adding toppings: ");
        for(int i = 0; i < toppings.size(); i++){
            if(i == toppings.size()-1){
                System.out.print( toppings.get(i));
            }else{
                System.out.print(toppings.get(i) + ",");
            }
        }
    }
    
    public void bake(){
        System.out.println("Bake for 25 minutes at 350");
    }
    
    public void cut(){
        System.out.println("Cutting the pizza into diagonal slices");
    }
    
    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;
    }

    public String getDough() {
        return dough;
    }

    public void setDough(String dough) {
        this.dough = dough;
    }

    public String getSauce() {
        return sauce;
    }

    public void setSauce(String sauce) {
        this.sauce = sauce;
    }

    @SuppressWarnings("rawtypes")
    public ArrayList getToppings() {
        return toppings;
    }

    @SuppressWarnings("rawtypes")
    public void setToppings(ArrayList toppings) {
        this.toppings = toppings;
    }
    
}
package com.zjut.json.factoryMethod;

/**
 * 具体风味的披萨
 * 
 * @author json
 *
 * @date 2013-5-7
 */
public class NYStyleCheesePizza extends Pizza {
    @SuppressWarnings("unchecked")
    public NYStyleCheesePizza(){
        setName("NY Style Sauce and cheese Pizza");
        setDough("Thin Crust Dough");
        getToppings().add("Grated Reggiano Cheese");
    }
}
package com.zjut.json.factoryMethod;

/**
 * 具体风味的Pizza
 * 
 * @author json
 *
 * @date 2013-5-7
 */
public class ChicagoStyleCheesePizza extends Pizza {
    @SuppressWarnings("unchecked")
    public ChicagoStyleCheesePizza(){
        setName("Chicago Style Sauce and cheese Pizza");
        setDough("Extra Thick Crust Dough");
        setSauce("Plum Tomato Sauce");
        getToppings().add("Shredded Mozzarella Cheese");
    }
    
    public void cut(){
        System.out.println("Cutting the pizza into square slices");
    }
}
package com.zjut.json.factoryMethod;

/**
 * 披萨商店
 * 
 * @author json
 *
 * @date 2013-5-7
 */
public abstract class PizzaStore {
    
    public final  Pizza orderPizza(final String type){
        Pizza pizza;
        pizza = createPizza(type);
        pizza.prepare();
        pizza.bake();
        pizza.cut();
        pizza.box();
        return pizza;
    }
    
    /**
     * 创建pizza的抽象方法
     * 
     * @param type pizza的类型那个
     * 
     * @return Pizza对象
     */
    protected abstract Pizza createPizza(final String type);
}
package com.zjut.json.factoryMethod;

/**
 * 具体披萨商店
 * 
 * @author json
 *
 * @date 2013-5-7
 */
public class NYPizzaStore extends PizzaStore {

    @Override
    protected Pizza createPizza(String type) {
        if("cheese".equals(type)){
            return new NYStyleCheesePizza();
        }
        return null;
    }

}
package com.zjut.json.factoryMethod;

/**
 * 具体披萨商店
 * 
 * @author json
 *
 * @date 2013-5-7
 */
public class ChicagoPizzaStore extends PizzaStore {

    @Override
    protected Pizza createPizza(String type) {
        if("cheese".equals(type)){
            return new ChicagoStyleCheesePizza();
        }
        return null;
    }

}

测试类:

package com.zjut.json.factoryMethod;

/**
 * @author json
 *
 * @date 2013-5-7
 */
public class PizzaStoreTest {

    public static void main(String[] args){
        PizzaStore nystore = new NYPizzaStore();
        PizzaStore chicagostore = new ChicagoPizzaStore();
        Pizza pizza = nystore.orderPizza("cheese");
        System.out.println("Json ordered a " + pizza.getName());
        pizza = chicagostore.orderPizza("cheese");
        System.out.println("Joe ordered a " + pizza.getName());
    }
}

测试结果:

收工!!!

posted on 2013-05-07 23:05  幸福从不迟疑  阅读(335)  评论(0编辑  收藏  举报