设计模式(五):《Head First设计模式》工厂模式

前言

接上篇设计模式(四):《Head First设计模式》工厂模式之简单工厂

概念

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

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

工厂方法

abstract Product factoryMethod(String type)
  • 工厂方法是抽象的,所以依赖子类来处理对象的创建
  • 必须返回一个产品,比如煎饼果子工厂必须返回煎饼果子
  • 参数不是必需的,根据需求来定

煎饼果子干大了

煎饼果子产业逐步扩大,煎饼果子研究室也持续出新品,并且出现地区风味了,但是煎饼的制作工艺和核心配方是一样的。

鉴于上述情况,总工厂负责生产,加盟店负责销售的模式不再适用。

Demo

以下只实现了临沂风味店,菜煎饼店同理~

煎饼果子总店

public abstract class JBGZStore {

    public Jianbingguozi orderJBGZ(String type) {
        Jianbingguozi jbgz;
        jbgz = createJBGZ(type);
        jbgz.prepare();
        jbgz.make();
        jbgz.cut();
        return jbgz;
    }
    
    // 工厂方法,由子类负责实现
    abstract Jianbingguozi createJBGZ(String type);
}

依照总店打造的分店(临沂风味煎饼果子总代理)

public class LinyiStore extends JBGZStore{

    @Override
    Jianbingguozi createJBGZ(String type) {
        Jianbingguozi jianbingguozi = null;
        if("乞丐版".equals(type)) {
            jianbingguozi = new LYQigaibanJBGZ();
        }else if("高配版".equals(type)) {
            jianbingguozi = new LYGaopeibanJBGZ();
        }else if("豪华版".equals(type)) {
            jianbingguozi = new LYHaohuabanJBGZ();
        }
        return jianbingguozi;
    }
}

产品-煎饼果子抽象类

public abstract class Jianbingguozi {

    String name;
    // 加什么
    ArrayList adders = new ArrayList<>(8);
    
    void prepare() {
        printf("开始准备制作" + name + "……");
        for(int i = 0; i < adders.size();i++) {
            printf("放 " + adders.get(i));
        }
    }
    
    // 正常的煎饼果子制作是一样的
    void make() {
        printf("制作煎饼");
    }
    
    // 是否需要拦腰切断
    void cut() {
        printf("不需要切开");
    }
    
    private void printf(String str) {
        System.out.println(str);
    }
}

产品实现--临沂风味丐版煎饼果子

public class LYQigaibanJBGZ extends Jianbingguozi{

    public LYQigaibanJBGZ() {
        name = "临沂风味丐版煎饼果子";
        adders.add("鸡蛋");
        adders.add("果子");
    }
}

产品实现--临沂风味高配版煎饼果子

public class LYGaopeibanJBGZ extends Jianbingguozi{

    public LYGaopeibanJBGZ() {
        name = "临沂风味高配版煎饼果子";
        adders.add("两个鸡蛋");
        adders.add("果子");
        adders.add("火腿肠");
    }
}

产品实现--临沂风味豪华版版煎饼果子

public class LYHaohuabanJBGZ extends Jianbingguozi{

    public LYHaohuabanJBGZ() {
        name = "临沂风味豪华版煎饼果子";
        adders.add("两个鸡蛋");
        adders.add("果子");
        adders.add("火腿肠");
        adders.add("鸡柳");
        adders.add("培根");
        adders.add("生菜");
    }
}

测试

public class JBGZTestDriver {

    public static void main(String[] args) {
        JBGZStore lyStore = new LinyiStore();
        Jianbingguozi lyjbgz = lyStore.createJBGZ("豪华版");
        System.out.println("土豪顾客点了个 " + lyjbgz.name);
    }
}    

Demo解析

跟上一篇文章的区别在于,我们将煎饼果子的制作权利下放到了产品的具体制作商那里了,而不是控制在总工厂,这里用的就是工厂方法模式

定义了一个创建对象的接口JBGZStore,但是由具体的煎饼果子商店决定要实例化哪个产品

abstract Jianbingguozi createJBGZ(String type);

上面的代码就是工厂方法,是一个抽象方法,具体实现由子类负责。这样就将实例化推迟到了子类当中。

书中是利用Pizza制作解析的,图示如下

图片来自《Head First 设计模式》

工厂方法模式与抽象工厂模式

  • 抽象工厂是创建一个产品家族,而工厂方法创建一个产品

  • 创建对象的方法不同

    • 工厂方法使用继承。利用工厂方法创建对象,需要扩展一个类,并覆盖它的工厂方法
    • 抽象工厂通过对象的组合。抽象工厂提供一个用来创建一个产品家族的抽象类型。这个类型的子类定义了产品被产生的方法。”把一群相关的产品集合起来“

    借用下书中的Pizza原料工厂例子,如下

    1. 定义抽象接口用来创建产品家族(原料):Interface PizzaIngredientFactory

    2. 两个子类(抽象工厂):纽约原料工厂,芝加哥原料工厂
      这两个子类负责原料生产,通常是通过工厂方法来实现的

    3. 所有的原料都是属于产品,正如上述工厂方法中的煎饼果子这个产品

你可能感兴趣的:(设计模式(五):《Head First设计模式》工厂模式)