前言
接上篇重学设计模式 (四):《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<String> 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 原料工厂例子, 如下
定义抽象接口用来创建产品家族 (原料):Interface PizzaIngredientFactory
两个子类 (抽象工厂): 纽约原料工厂, 芝加哥原料工厂
这两个子类负责原料生产, 通常是通过工厂方法来实现的
所有的原料都是属于产品, 正如上述工厂方法中的煎饼果子这个产品
来源: http://www.jianshu.com/p/fcf7f1256bb5