【设计模式】之抽象工厂(Abstract Factory)

抽象工厂的定义为:不需要指定具体的类,为创建一系列有关联或有依赖关系的对象提供一个接口(Provide an interface for creating families of related or dependent objects without specifying their concrete  classes)。


由定义可以看出,抽象工厂生产的是一系列产品(families of products),这就是与工厂方法(Factory Method)的区别所在;还有一点就是生产出的产品具有相关性(related or dependent),因为同一类别的产品是在一个工厂中生产的,因而抽象工厂可以满足这个约束(constraint),同时这点也是在使用抽象工厂模式时需要注意的事项 ---- 保持对象的一致性。


抽象工厂可以不抽象,这样它可以同时被当作抽象工厂和具体工厂,子类工厂在继承的时候可以选择自己需要的产品去生产,不必生产每一种产品。


抽象共产生产的每一种产品可以使用工厂模式,如果产品的种类太多,为避免过多的继承,则可以使用原型模式(Prototype)。


实例代码如下(java)

1 首先定义一个工厂的接口,接口中定义了生产每一种产品的方法,用到了工厂方法(Factory Method)。

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

2 定义一个具体的工厂

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[] createVigges() {
        Veggies[] veggies = { new Garlic(), new Onion(), new Mushroom(), new RedPepper() };
        return veggies;
    }

    public Pepperoni createPepperoni() {
        return new SlicedPepperoni();
    }

    public Clams createClam() {
        return new FreshClams();
    }
}

3 定义产品的基类

public abstract class Pizza {
    String name;
    String dough;
    String sauce;
    Veggies[] veggies;
    Cheese cheese;
    Pepperoni pepperoni;
    Clams 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 setName(String name) {
        this.name = name;
    }

    String getName() {
        return name;
    }

    public String toString() {
        // code to print pizza here
    }
}

3 具体的产品类

public class CheesePizza extends Pizza {
    PizzaIngredientFactory ingredientFactory;

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

    void prepare() {
        System.out.println("Preparing " + name);
        dough = ingredientFactory.createDough();
        sauce = ingredientFactory.createSauce();
        cheese = ingredientFactory.createCheese();
    }
}
public class ClamPizza extends Pizza {
    PizzaIngredientFactory ingredientFactory;

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

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

3 使用工厂类

public class NYPizzaStore extends PizzaStore {
    protected 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");
        } else if (item.equals("clam")) {
            pizza = new clamPizza(ingredientFactory);
            pizza.setName("New York Style Clam Pizza");
        } else if (item.equals("pepperoni")) {
            pizza = new PepperoniPizza(ingredientFactory);
            pizza.setName("New York Style Pepperoni Pizza");
        }
        return pizza;
    }
}

由于常常只用到一个工厂类的实例,因此可以把子类工厂类定义为singleton,这样也可以使用到lazy initialization。



你可能感兴趣的:(【设计模式】之抽象工厂(Abstract Factory))