工厂模式(创建型)

一:相关定义

这里的工厂模式分为三种:简单工厂模式工厂模式抽象工厂模式

简单工厂模式:其实不算是一种模式,而是一种编程习惯,这里就不定义了,因为我也没找到睡觉

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

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


二:相关类图和示例

简单工厂(直接上示例图):


下面是关键代码:

public class PizzaStore{
    SimplePizzaFactory factory;
    public PizzaStore(SimplePizzaFactory factory){
        this.factory = factory;
    }
    public Pizza orderPizza(String type){
        Pizza pizza;
        pizza = factory.createPizza(type);
        pizza.prepare();
        pizza.bake();
        pizza.cut();
        pizza,box();
        return pizza;
    }
    //其他方法
}

示例图中和代码都挺清楚了,这里就不赘述啦。


工厂模式类图:


Creator中定义abstract Product factoryMethod(String type)抽象方法,由子类来实现;这样,定义的不同的子类工厂,将返回不同的创建的Product。具体看下面示例:

工厂模式示例:


我们来看看这个关于Pizza(比萨)的工厂模式核心代码:

//PizzaStore的子类在createPizza()方法中,处理对象的实例化。
public abstract class PizzaStore{
    public Pizza orderPizza(String type){
        Pizza pizza;
        pizza = createPizza(type);

        pizza.prepare();
        pizza.bake();
        pizza.cut();
        pizza.box();

        return pizza;
    }
    //此方法如同一个工厂
    protected abstract Pizza createPizza(String type);
}

上述为抽象的创建者(Creator),在orderPizza方法中定义了烘培Pizza的流程(使用模板模式),而将创建不同Pizza的责任交给了子类来实现;例如:

public class NYPizzaStore extends PizzaStore{
    Pizza createPizza(String item){
        if(item.equals("cheese")){
            return new NYStyleCheesePizza();
        }else if(item.equals("veggie")){
            return new NYStyleVeggiePizza();
        }
    }
}
public class ChicagoPizzaStore extends PizzaStore{
    Pizza createPizza(String item){
        if(item.equals("cheese")){
            return new ChicagoStyleCheesePizza();
        }else if(item.equals("veggie")){
            return new ChicagoStyleVeggiePizza();
        }
    }
}

这里,关于Pizza的定义我们就进行省略了。下面来看如何使用:

//建立两个不同的店,分别进行下订单
PizzaStore nyStore = new NYPizzaStore();
PizzaStore chicagoStore = new ChicagoPizzaStore();

Pizza pizza = nyStore.orderPizza("cheese");
System.out.println("Order a "+pizza.getName());

pizza = chicagoStore.orderPizza("cheese");
System.out.println("Order a "+pizza.getName());

这样,我们就实现了在各个地域中比萨店自己的独特风味(纽约比萨饼薄,芝加哥比萨饼厚等)。

在这个示例中,我们看看工厂模式起到的作用:Pizza在纽约(NY)和芝加哥(Chicago)都有分店。为了确保质量,制作Pizza的工序固定(prepare-box),且都有cheese(奶酪风味)和Veggie(素食风味)等不同口味;但是NY和Chicago两地的Pizza店对于一种风味(如cheese)的Pizza也都有自己的特色(如微辣和变态辣),这时,不能使用简单工厂模式来创建Pizza对象了,应该交由各地的工厂来创建自己独特的风味Pizza,如此便可使用工厂模式。在上图,真正的创建Pizza的步骤交给了下面的不同的子类实现,父类仅仅确保了制作Pizza的流程。


抽象工厂模式类图:


结合下面的例子来进行理解:

抽象工厂模式示例(摘自Headfirst 设计模式)


先看看这个例子中,使用抽象工厂模式的目的是什么:在上面例子中,工厂方法使得各地都可以生产自己独特风味的Pizza,但是为了保证质量,生产Pizza的原料我们想要保证都是自己的原料,这样,需要各地都使用我们运输给他们的一组原料来创建Pizza,这样就用到了抽象工厂模式,下面看代码:

先看Pizza(前面懒,就没写,到这里了没法避免)

public abstract class Pizza{
    String name;//名字              //每个Pizza都持有一组在准备时会用到的原料
    Dough dough;//面团
    Sauce sauce;//酱汁
    Veggies[] veggies;//蔬菜
    Cheese cheese;//奶酪
    Pepperoni peperoni;//意大利腊肠
    Clams clam;//蛤

    //将prepare设置成抽象(原来不是哦)。在此方法中,我们收集Pizza的所需的原料(来自我们的原料工厂:固定的一组原料)
    abstract void prepare;
    
    void bake(){
        System.out.println("bake for 25 minutes at 350");//烤
    }
    void cut(){
        //切
    }
    void box(){
        //装盒
    }
    void setName(String name){
        this.name = name;
    }
    String getName(){
        return name;
    }
    public String toString{
        //打印比萨
    }

}
再看我们的抽象工厂接口PizzaIngredientFactory:
public interface PizzaIngerdFactory{
    public Dough createDough();
    public Sauce createSauce();
    public Cheese createCheese();
    public Veggies[] createVeggies();
    public Pepperoni createPepperoni();
    public Clam createClam();
}

下面是纽约(NY)的原料工厂:

//实现工厂接口
public class NYPizzaIngredientFactory implements PizzaIngredientFactory{
    //对于原料家族的每一种原料,我们都提供了纽约(NY)版本
    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()};
        return veggies;
    }
    public Pepperoni createPepperoni(){
        return new SlicedPepperoni();
    }
    public Clams createClam(){
        return new FreshClams();
    }
}

上面,就实现了我们的纽约(NY)原料工厂(芝加哥chicago的Factory类似),来看看 如何使用吧:

public class cheesePizza extends Pizza{
    PizzaIngredientFactory ingredientFactory;
    //每个Pizza需要从构造函数取得一个工厂,用以提供原料
    public CheesePizza(PizzaIngredientFactory ingredientFactory){
        this.ingredientFactory = ingredientFactory;
    }
    void prepare(){
        System.out.println("Prepareing "+name);
        dough = ingredientFactory.createDough();
        sauce = ingredientFactory.createSauce();
        cheese = ingredientFactory.createCheese();
    }
}

这样我们创建Pizza时,就可以这样:

public class NYPizzaStore extends PizzaStore{
    protected Pizza createPizza(String item){
    Pizza pizza = null;
    PizzaIngredientFactory ingredientFactory = new NYPizzaIngredientFactory();

    if("cheese".equals(item)){
        pizza = new CheesePizza(ingredientFactory);
        pizza.setName("NY Style Cheese Pizza");
    }else if("veggies".equals(item)){
        pizza = new VeggiePizza(ingredientFactory);
        pizza.setName("NY Style Veggie Pizza");
    }
    return pizza;
}

这里,我们使用组合的方式,传递一个原料工厂,然后创建一整个家族的原料对象,这就是抽象工厂模式了。


参考书籍《head first 设计模式》《大话设计模式》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值