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

来源:互联网 发布:都匀皓轩网络 编辑:程序博客网 时间:2024/06/15 16:37

抽象工厂的定义为:不需要指定具体的类,为创建一系列有关联或有依赖关系的对象提供一个接口(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。



原创粉丝点击