工厂模式详解(简单工厂+工厂方法+抽象工厂)

这篇文章是对三个工厂模式的分析总结,把三个放在一起希望可以帮到大家更好的理解工厂模式。本文的例子选用的是《head first 设计模式》一书中的披萨店。
问题描述:一个披萨店里有芝士披萨和蔬菜披萨,客人到店里买预定披萨,可能你的代码会这么写:

public void orderPizza(String type){
        Pizza pizza = null;

        if (type.equals("cheese")){
            pizza = new CheesePizza();
        }else if (type.equals("veggie")){
            pizza = new VeggiePizza();
        }

        if (pizza != null){
            pizza.prepare();
            pizza.bake();
            pizza.cut();
            pizza.box();
        }

    }

如果你要添加店里的披萨口味,那你需要添加更多的if else,如果有些口味销量不好,那你有需要去删除多余的if else;这样频繁的修改明显不是我们想要的。这里就要用到简单工厂模式了。

简单工厂模式

定义:又叫做静态工厂方法模式,是由一个工厂对象决定创建出哪一种产品类的实例。
下面先给出uml类图


添加了一个新的工厂类,通过工厂类的createPizza()方法来制作客户需要的披萨具体的代码如下:
SimplePizzaFactory:

public class SimplePizzaFactory {

    public static Pizza createPizza(String type){
        Pizza pizza = null;

        if (type.equals("cheese")){
            pizza = new CheesePizza();
        }else if (type.equals("veggie")){
            pizza = new VeggiePizza();
        }
        return pizza;
    }

}

写一个披萨的抽象类,所有的披萨继承这个抽象类,我把披萨的切割和包装当做是不变的步骤,不同的披萨准备方法和烘焙方法不一样。
Pizza:

public abstract class Pizza {

    public abstract void prepare();

    public abstract void bake();

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

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

CheesePizza:

public class CheesePizza extends Pizza{
    @Override
    public void prepare() {
        System.out.println("prepare CheesePizza");
    }

    @Override
    public void bake() {
        System.out.println("bake CheesePizza");
    }
}

VeggiePizza:

public class VeggiePizza extends Pizza{

    @Override
    public void prepare() {
        System.out.println("prepare VeggiePizza");
    }

    @Override
    public void bake() {
        System.out.println("bake VeggiePizza");
    }
}

PizzaStore:

public class PizzaStore {

    public void orderPizza(String type){
        Pizza pizza;

        pizza = SimplePizzaFactory.createPizza(type);

        if (pizza != null){
            pizza.prepare();
            pizza.bake();
            pizza.cut();
            pizza.box();
        }


    }

    public static void main(String[] args) {
        PizzaStore pizzaStore = new PizzaStore();

        pizzaStore.orderPizza("cheese");

        pizzaStore.orderPizza("veggie");


    }
}

截图:

到这里算是解决一开始提到的频繁修改问题,接下来披萨店有了新的需求,披萨店要在芝加哥和纽约开分店,但是芝加哥和纽约地区不同口味也会不同。接下来就要通过工厂方法模式来解决问题。

工厂方法模式

uml类图:

这里修改了PizzaStore类,新增了NYPizzaStore和ChicagoPizzaStore
代码如下:
Pizza:

public abstract class Pizza {

    public abstract void prepare();

    public abstract void bake();

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

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

NYStyleVeggiePizza:

public class NYStyleVeggiePizza extends Pizza{

    @Override
    public void prepare() {
        System.out.println("prepare NYStyleVeggiePizza");
    }

    @Override
    public void bake() {
        System.out.println("bake NYStyleVeggiePizza");
    }
}

NYStyleCheesePizza:

public class NYStyleCheesePizza extends Pizza{

    @Override
    public void prepare() {
        System.out.println("prepare NYStyleCheesePizza");
    }

    @Override
    public void bake() {
        System.out.println("bake NYStyleCheesePizza");
    }
}

PizzaStore:

/**
 * Created by zhaoyigang on 2017/6/3.
 */
public abstract class PizzaStore {

    protected abstract Pizza createPizza(String type);

    public void orderPizza(String type){

        Pizza pizza;

        pizza = createPizza(type);

        if (pizza != null){
            pizza.prepare();
            pizza.bake();
            pizza.cut();
            pizza.box();
        }

    }


    public static void main(String[] args) {
        ChicagoPizzaStore chicagoPizzaStore = new ChicagoPizzaStore();

        chicagoPizzaStore.orderPizza("cheese");

        NYPizzaStore nyPizzaStore = new NYPizzaStore();

        nyPizzaStore.orderPizza("veggie");
    }
}

ChicagoPizzaStore:

public class ChicagoPizzaStore extends PizzaStore{
    @Override
    protected Pizza createPizza(String type) {
        if (type.equals("cheese")){
            return new ChicagoStyleCheesePizza();
        }else if (type.equals("veggie")){
            return new ChicagoStyleVeggiePizza();
        }
        return null;
    }
}

NYPizzaStore:

public class NYPizzaStore extends PizzaStore{

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

截图:

相比之下,简单工厂模式只有一个工厂,工厂方法模式对每一个产品都有相应的工厂。纽约和芝加哥的披萨店分别有不同的工厂,生产不同口味的披萨,满足不同客户的需求。
如果要确保每个披萨店的原料标准化,打算建造一个原料生产的工厂,并将原料运送到各家加盟店。那么就要用到抽象工厂方法了。

抽象工厂方法

定义:为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类。
UML类图:

代码如下:
Pizza:

public abstract class Pizza {

    private Materiel materiel;

    public abstract void prepare();

    public abstract void bake();

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

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

CheesePizza:

public class CheesePizza extends Pizza{

    private MaterielFactory materielFactory;

    public CheesePizza(MaterielFactory materielFactory){
        this.materielFactory = materielFactory;
    }


    @Override
    public void prepare() {
        materielFactory.createMateriel();
        System.out.println("prepare cheesePizza");
    }

    @Override
    public void bake() {
        System.out.println("bake cheesePizza");
    }
}

MaterielFactory:

public interface MaterielFactory {

    public Materiel createMateriel();

}

NYMaterielFactory:

public class NYMaterielFactory implements MaterielFactory{
    @Override
    public Materiel createMateriel() {
        System.out.println("prepare NYPizzaMateriel");
        return new NYPizzaMateriel();
    }
}

ChicagoMaterielFactory:

public class ChicagoMaterielFactory implements MaterielFactory{
    @Override
    public Materiel createMateriel() {
        System.out.println("prepare ChicagoPizzaMateriel");
        return new ChicagoPizzaMateriel();
    }
}

PizzaStore:

public abstract class PizzaStore {

    protected abstract Pizza createPizza(String type);

    public void orderPizza(String type){

        Pizza pizza;

        pizza = createPizza(type);

        if (pizza != null){
            pizza.prepare();
            pizza.bake();
            pizza.cut();
            pizza.box();
            System.out.println("finished");
            System.out.println("***************");
        }

    }


    public static void main(String[] args) {
        ChicagoPizzaStore chicagoPizzaStore = new ChicagoPizzaStore();
        chicagoPizzaStore.orderPizza("cheese");

        NYPizzaStore nyPizzaStore = new NYPizzaStore();
        nyPizzaStore.orderPizza("veggie");
    }
}

ChicagoPizzaStore:

public class ChicagoPizzaStore extends PizzaStore{
    @Override
    protected Pizza createPizza(String type) {

        ChicagoMaterielFactory chicagoMaterielFactory = new ChicagoMaterielFactory();

        if (type.equals("cheese")){
            return new CheesePizza(chicagoMaterielFactory);
        }else if (type.equals("veggie")){
            return new VeggiePizza(chicagoMaterielFactory);
        }
        return null;
    }
}

NYPizzaStore:

public class NYPizzaStore extends PizzaStore{

    @Override
    protected Pizza createPizza(String type) {

        NYMaterielFactory materielFactory = new NYMaterielFactory();

        if (type.equals("cheese")){
            return new CheesePizza(materielFactory);
        }else if (type.equals("veggie")){
            return new VeggiePizza(materielFactory);
        }
        return null;
    }
}

相比之下,工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个。工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值