读《HeadFirst设计模式》笔记之工厂模式

工厂模式有三种:简单工厂模式工厂方法模式抽象工厂模式

简单工厂模式:定义一个工厂类,它可以根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父类。

举个栗子:

咱们有一个披萨店,有很多种类的披萨。有一天一个顾客点了一份“素食披萨”。我们应该怎么下单并制作披萨呢?

先看一种low的做法:

public class PizzaStore {
    public Pizza OrderPizza(String type) {
        Pizza pizza;
    
        // 选择哪种披萨
        if (type.equals("cheese")) {
            pizza = new CheesePizza();
        } else if (type.equals("clam")) {
            pizza = new ClamPizza();
        } else if (type.equals("veggie")) {
            pizza = new VeggiePizza();
        }

        // 制作
        pizza.prepare();
        pizza.bake();
        pizza.cut();
        pizza.box();
    
        return pizza;
    }
}

这种把选择披萨和制作过程全放在一起,如果新推出一款披萨就要修改OrderPizza方法,不符合开闭原则。

利用简单工厂模式:

public class PizzaStore {
    SimplePizzaFactory factory;

    public PizzaStore(SimplePizzaFactory factory) {
        this.factory = factory;
    }

    public Pizza OrderPizza(String type) {
        // 选择哪种披萨
        Pizza pizza = factory.createPizza(type);

        // 制作
        pizza.prepare();
        pizza.bake();
        pizza.cut();
        pizza.box();
            
        return pizza;
    }
}


// 简单工厂类
public class simplePizzaFactory {
    public Pizza createPizza(String type) {
        Pizza pizza;

        // 选择哪种披萨
        if (type.equals("cheese")) {
            pizza = new CheesePizza();
        } else if (type.equals("clam")) {
            pizza = new ClamPizza();
        } else if (type.equals("veggie")) {
            pizza = new VeggiePizza();
        }

        return pizza;
    }
}

总结:与其说简单工厂是一种模式,还不如说是一种编码习惯。就是把创建对象部分进行封装。

 

工厂方法模式:一个产品对应一个工厂,解决了开放封闭原则。每个工厂只能创建一个产品的实例。每次新增一个产品时,就新增一个对应的工厂。

举个栗子:

由于我们的披萨广受大家的喜爱,我们要去北京开分店啦!!!(分店就是产品)

我们需要利用简单工厂模式创建两个工厂,分别是SHPizzaFactory和BJPizzaFactory。

// 上海订一份披萨
SHPizzaFactory shFactory = new SHPizzaFactory();
PizzaStore shStore = new PizzaStore(shFactory);
shStore.orderPizza("veggie");


// 北京订了一份披萨
BJPizzaFactory bjFactory = new BJPizzaFactory();
PizzaStore bjStore = new PizzaStore(bjFactory);
bjStore.orderPizza("veggie");

如果北京的顾客和上海的顾客有不同的口味怎么办?

创建一个披萨店抽象类:

public abstract class PizzaStore {
    public abstract Pizza createPizza(String type);

    public Pizza orderPizza(String type) {
       Pizza pizza = this.createPizza(type);
       ...
    }
}

创建北京披萨店和上海披萨店:(允许子类做决定)

public calss BJPizzaStore extends PizzaStore {
    public Pizza createPizza(String type) {
        Pizza pizza;

        // 选择哪种披萨
        if (type.equals("cheese")) {
            pizza = new BJStyleCheesePizza();
        } else if (type.equals("clam")) {
            pizza = new BjStyleClamPizza();
        } else if (type.equals("veggie")) {
            pizza = new BJStyleVeggiePizza();
        }

        return pizza;
    }
}

public calss SHPizzaStore extends PizzaStore {
    public Pizza createPizza(String type) {
        Pizza pizza;

        // 选择哪种披萨
        if (type.equals("cheese")) {
            pizza = new SHStyleCheesePizza();
        } else if (type.equals("clam")) {
            pizza = new ShStyleClamPizza();
        } else if (type.equals("veggie")) {
            pizza = new SHStyleVeggiePizza();
        }

        return pizza;
    }
}

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

一组相关的产品为一个产品族

举个栗子:

咱们的披萨店,要控制使用同样的配料,所以经讨论,需要建一个配料加工厂。不同的披萨店都从配料工厂中获取配料。

创建配料工厂接口,创建各种配料对象

public interface PizzaIngredientFactory {
    public Dough createDouch();
    public Sauce createSauce();
    public Cheese createCheese();
}

创建一个上海配料工厂实例:

public class BJPizzaIngredientFactory implements PizzaIngredientFactory {
    public Dough createDouch() {
        return new ThinCrustDouch();
    }

    public Sauce createSauce() {
        return new MarinaraSauce();
    }

    public Cheese createCheese() {
        return new ReggianoCheese();
    }
}

披萨抽象类:

public abstract class Pizza{
    Dough dough;
    Sauce sauce;
    Cheese cheese;

    // 准备配料
    abstract void prepare();

    void bake() {
       System.out.println("Back for 25 minutes");
    }

    void cut() {
        System.out.println("cut the pizza");
    }

    void box() {
        System.out.println("Place pizza into box");
    }
}

创建一个披萨实例:

public class CheesePizza extends Pizza {
    PizzaIngredientFactory ingredientFactory;

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

    void prepare() {
        dough = ingredientFactory.createDough();
        sauce = ingredientFactory.createSauce();
        cheese = ingredientFactory.createCheese();
    }
}

再回到北京披萨店:

public calss BJPizzaStore extends PizzaStore {
    public Pizza createPizza(String type) {
        Pizza pizza;
        PizzaIngredientFactory ingredientFactory = new BJPizzaIngredientFactory();

        // 选择哪种披萨
        if (type.equals("cheese")) {
            pizza = new CheesePizza(ingredientFactory);
        } else if (type.equals("clam")) {
            pizza = new ClamPizza(ingredientFactory);
        } else if (type.equals("veggie")) {
            pizza = new VeggiePizza(ingredientFactory);
        }

        return pizza;
    }
}

转载于:https://my.oschina.net/suyain/blog/1923780

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值