设计模式 - 学习笔记 - 工厂模式Factory Pattern

  • 1. 简单工厂
    • 1.1 应用场景
    • 1.2 UML
    • 1.3 优劣分析
      • 好处
      • 缺点
    • 1.4 代码示例
      • 抽象产品 AbstractProduct(米粉)
      • 具体产品类(牛肉粉、酸辣粉)
      • 工厂类 Factory (米粉店)
      • 客户端 SimpleFactoryPatternTest
  • 2. 工厂方法模式
    • 2.1 应用场景
    • 2.2 UML
    • 2.3 优劣分析
      • 好处
      • 缺点
    • 2.4 代码示例
      • 抽象产品 AbstractProduct(米粉)
      • 具体产品类(牛肉粉、酸辣粉)
      • 抽象工厂 AbstractFactory(米粉店)
      • 具产工厂(牛肉粉店、酸辣粉店)
      • 客户端 FactoryMethodPatternTest
  • 3 抽象工厂模式
    • 3.1 应用场景
    • 3.2 UML
    • 3.3 优劣分析
      • 好处
      • 缺点
    • 3.4 代码示例
      • 抽象产品
      • 具体产品类
      • 抽象工厂 AbstractFactory (米粉店)
      • 具体产品
      • 客户端 AbstractFactoryPatternTest
  • 总结
  • 参考资料

1. 简单工厂

1.1 应用场景

当创建一个对象A的过程比较复杂时,为了把业务逻辑解耦出来,我们封装类B来实现这个创建过程,这个类A就好比产品,创建它的类B就好比工厂。
简单工厂就是 if...else + 接口 的基本用法。根据条件判断返回实现类的实例,然后用个接口引用接收。

1.2 UML

1.3 优劣分析

好处

  • 将创建产品的工作封装在一个工厂中,与客户端解耦。
  • 实现原理简单: if...else + 多态 的应用。

缺点

  • 客户端需要知道所有策略。(实际应用中可以考虑与其它模式相结合)
  • 添加or修改任意一个产品就需要修改工厂类。(违反开闭原则、单一职责原则)
  • 添加新产品就是加 if...esle,产品少还行,产品多了不好维护。(违反开闭、单一职责)

1.4 代码示例

抽象产品 AbstractProduct(米粉)

public interface AbstractProduct {void show();
}

具体产品类(牛肉粉、酸辣粉)

public class 牛肉粉Impl implements AbstractProduct {public void show() {System.out.println("这是一碗:牛肉粉");}
}public class 酸辣粉Impl implements AbstractProduct {public void show() {System.out.println("这是一碗:酸辣粉");}
}

工厂类 Factory (米粉店)

/*** 米粉店 (工厂类)*/
public class Factory {/** 方便客户端使用,把所有产品列出来。(其实搞个枚举也不错) */public static final String 牛肉粉 = "牛肉粉";public static final String 酸辣粉 = "酸辣粉";/*** 使用 下粉 方法获取产品* @param 米粉名字* @return*/public AbstractProduct 下粉(String 米粉名字){if(Factory.牛肉粉.equalsIgnoreCase(米粉名字)){return new 牛肉粉Impl();} else if(Factory.酸辣粉.equalsIgnoreCase(米粉名字)){return new 酸辣粉Impl();}return null;}
}

客户端 SimpleFactoryPatternTest

public class SimpleFactoryPatternTest {public static void main(String[] args) {Factory 粉店 = new Factory();AbstractProduct 牛肉粉 = 粉店.下粉(Factory.牛肉粉);AbstractProduct 酸辣粉 = 粉店.下粉(Factory.酸辣粉);牛肉粉.show();酸辣粉.show();}
}

2. 工厂方法模式

2.1 应用场景

工厂方法模式可以弥补简单工厂存在的问题(开闭原则、单一职责原则)

2.2 UML

2.3 优劣分析

好处

  • 提取出工厂接口,每个具体工厂专心生产一种产品。(职责更单一)

    • 新增产品时不需要修改原有的工厂类。只需要成对添加XX工厂XX产品即可。
    • 修改指定产品时,也不用动其它的工厂和产品

缺点

  • 一个工厂只能生产一个产品,新增产品时需要成对的添加工厂产品
  • 引入了AbstractFactory加大了理解难度。(这点成本可以通过经验抵消)

2.4 代码示例

抽象产品 AbstractProduct(米粉)

public interface AbstractProduct {void show();
}

具体产品类(牛肉粉、酸辣粉)

public class 牛肉粉Impl implements AbstractProduct {public void show() {System.out.println("这是一碗:牛肉粉");}
}
public class 酸辣粉Impl implements AbstractProduct {public void show() {System.out.println("这是一碗:酸辣粉");}
}

抽象工厂 AbstractFactory(米粉店)

为了上下文统一,这里还是写米粉店。但是理解成加工米粉的车间更合适。

public interface AbstractFactory {AbstractProduct 下粉();
}

具产工厂(牛肉粉店、酸辣粉店)

牛肉粉店:加工牛肉粉的车间。
酸辣粉店:加工酸辣粉的车间。

public class 牛肉粉店Impl implements AbstractFactory {@Overridepublic AbstractProduct 下粉() {System.out.println("下了一碗牛肉粉");return new 牛肉粉Impl();}
}public class 酸辣粉店Impl implements AbstractFactory {@Overridepublic AbstractProduct 下粉() {System.out.println("下了一碗酸辣粉");return new 酸辣粉Impl();}
}

客户端 FactoryMethodPatternTest

public class FactoryMethodPatternTest {public static void main(String[] args) {//客人想吃牛肉粉,找牛肉粉店AbstractFactory 牛肉粉店 = new 牛肉粉店Impl();AbstractProduct product牛肉粉 = 牛肉粉店.下粉();product牛肉粉.show();//客人想吃酸辣粉,找酸辣粉店AbstractFactory 酸辣粉店 = new 酸辣粉店Impl();AbstractProduct product酸辣粉= 酸辣粉店.下粉();product酸辣粉.show();}
}

3 抽象工厂模式

3.1 应用场景

上面说的是一个工厂只生产一个产品。现实中肯定要推出尽可能多的品种来满足食客的需求。所以一家粉店,会做N多种米粉

  • 横向是产品簇:可以理解为品牌。同一品牌(张记)下有 N 种产品。
  • 纵向是产品等级 :可以理解为某类产品。牛肉粉是一类产品。只要复合标准规范,谁家都能生产。只是各有特色。
  • 抽象产品:对应标准规范,定义产品应该具备的能力或条件。(比如:每碗牛肉占比>= 7.5%的才能称为牛肉粉)
  • 产品实现:对应具体的产品(比如:一碗牛肉占比>= 7.5%的米粉)
  • 抽象工厂:定义品牌有生产哪些抽象产品的能力(比如一个合格的粉店最少能能生产2种以上米粉)
  • 具体工厂:张、王、李、赵的粉店

3.2 UML

3.3 优劣分析

好处

  • 同事们拼单点一家店的米粉,只需要创建一个工厂。
  • 如果还有煎蛋、酸笋、牛肉等加码需求,也可以在一个工厂里搞定。(不至于点了张记的米粉,又点了王记的煎蛋。现实中这两样是无法组合的。)

缺点

  • 添加产品簇好办,添加产品等级结构,就要破坏开闭原则了。

    • 比如新开了一家黄记粉店,它家一样可以卖牛肉粉、酸辣粉、螺丝粉、三鲜粉。张、王、李、赵的粉店不需要任何调整。
    • 但如果要上新品。比如最近拉面比较火爆,所有店家纷纷推出自家的拉面。所有粉店的厨子都要学习新技能(加代码),所有粉店都要购置做拉面的相关装备道具。也就是要修改工厂类了。

3.4 代码示例

抽象产品

两种大家熟悉的米粉:牛肉粉 、酸辣粉

public interface I米粉 {void 吃粉();
}
public interface I牛肉粉 extends I米粉 {}
public interface I酸辣粉 extends I米粉 {}

具体产品类

张记、王记两家不同粉店做的:牛肉粉 、酸辣粉

public class 张记牛肉粉Impl implements I牛肉粉 {@Overridepublic void 吃粉() {System.out.println("这是一碗:张记牛肉粉");}
}public class 张记酸辣粉Impl implements I酸辣粉 {@Overridepublic void 吃粉() {System.out.println("这是一碗:张记酸辣粉");}
}public class 王记牛肉粉Impl implements I牛肉粉 {@Overridepublic void 吃粉() {System.out.println("这是一碗:王记牛肉粉");}
}public class 王记酸辣粉Impl implements I酸辣粉 {@Overridepublic void 吃粉() {System.out.println("这是一碗:王记酸辣粉");}
}

抽象工厂 AbstractFactory (米粉店)

所有的米粉店会卖:牛肉粉 、酸辣粉

public interface AbstractFactory {I牛肉粉 下牛肉粉();I酸辣粉 下酸辣粉();
}

具体产品

张记、王记两家的牛肉粉 、酸辣粉口味可是不同。

/*** 张记米粉店 (具体工厂)*/
public class 张记米粉店Impl implements AbstractFactory {@Overridepublic I牛肉粉 下牛肉粉() {System.out.println("用张记祖传秘方,下了一碗牛肉粉");return new 张记牛肉粉Impl();}@Overridepublic I酸辣粉 下酸辣粉() {System.out.println("用张记祖传秘方,下了一碗酸辣粉");return new 张记酸辣粉Impl();}
}/*** 王记米粉店 (具体工厂)*/
public class 王记米粉店Impl implements AbstractFactory {@Overridepublic I牛肉粉 下牛肉粉() {System.out.println("用王记祖传秘方,下了一碗牛肉粉");return new 王记牛肉粉Impl();}@Overridepublic I酸辣粉 下酸辣粉() {System.out.println("用王记祖传秘方,下了一碗酸辣粉");return new 王记酸辣粉Impl();}
}

客户端 AbstractFactoryPatternTest

public class 客人{I米粉 米粉 = null;public static void 买牛肉粉(I牛肉粉 牛肉粉) {System.out.println("花掉20块");米粉 = 牛肉粉;}public static void 买酸辣粉(I酸辣粉 酸辣粉) {System.out.println("花掉15块");米粉 = 酸辣粉;}public static void 嗦粉() {System.out.println("开始痛快的嗦粉!");米粉.吃粉();}
}

客人张记吃了一碗牛肉粉,又到王记吃了一碗酸辣粉

public class AbstractFactoryPatternTest {public static void main(String[] args) {AbstractFactory 米粉店 = null;米粉店 = new 张记米粉店Impl();客人.买牛肉粉(米粉店.下牛肉粉());客人.嗦粉();米粉店 = new 王记米粉店Impl();客人.买酸辣粉(米粉店.下酸辣粉());客人.嗦粉();}
}

总结

  • 三个工厂并不是升级关系,而是适应不同的业务场景。
  • 如果后续才品很多,就难免会有一堆工厂。
  • 现实要与其他模式组合使用才靠谱。

参考资料

图说设计模式:工厂模式

设计模式 - 学习笔记 - 工厂模式Factory Pattern相关推荐

  1. 设计模式学习笔记——工厂(Factory)模式

    设计模式学习笔记--工厂(Factory)模式 @(设计模式)[设计模式, 工厂模式, factory] 设计模式学习笔记工厂Factory模式 基本介绍 工厂案例 类图 实现代码 framework ...

  2. 设计模式(四)——工厂模式(Factory Pattern)

    工厂模式(Factory Pattern) 意义 工厂模式 实现了创建者和调用者的分离.将实例化对象的代码提取出来,放到一个类中统一管理和维护,达到和主项目的依赖关系的解耦.从而提高项目的扩展和维护性 ...

  3. 设计模式 ~ 创建型模式 ~ 工厂模式 ~ Factory Pattern。

    设计模式 ~ 创建型模式 ~ 工厂模式 ~ Factory Pattern. 文章目录 设计模式 ~ 创建型模式 ~ 工厂模式 ~ Factory Pattern. eg. 简单工厂模式. 结构. 优 ...

  4. 设计模式-工厂模式 Factory Pattern(简单工厂、工厂方法、抽象工厂)

    工厂模式 Factory Pattern(简单工厂.工厂方法.抽象工厂) 工厂模式-创建型模式-提供了创建对象的最佳方式. 在工厂模式中,创建对象时不会对客户端暴露创建逻辑,并且是通过一个共同的接口来 ...

  5. 【设计模式】工厂模式 Factory Pattern

    1)简单工厂(不是模式) 简单工厂只是一种变成习惯,并非23种设计模式之一. 简单工厂提供将实例话那种类型留给运行时判断,而非编译时指定.简单工厂模式就是由一个工厂类根据传入的参数决定创建出哪一个类的 ...

  6. JAVA设计模式Design Pattern→单例模式Singleton Pattern、工厂模式Factory Pattern、代理模式Proxy Pattern

    私有化构造函数的类可以提供相应的 "接口"(一般就是静态方法)来返回自己的唯一实例供外部调用,像这样的确保只生成一个实例的模式被称作单例模式. 工厂模式,一个模型,用来大规模的生产 ...

  7. 设计模式之略见一斑(工厂模式Factory)

    在开发中其实我们已经不知道用到了设计模式中的很多模式 ,只是有些我们还未知它具体是哪种模式来着.如工厂模式,单例,适配,外观模式等一些常见模式. 下面是自己学习的一些相关笔记,以做备忘录. 1.工厂模 ...

  8. 设计模式学习之工厂模式(附demo)

    介绍 工厂模式(Factory Pattern) 是 Java 中最常用的设计模式之一.这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式. 在工厂模式中,我们在创建对象时不会对客户端暴 ...

  9. Java设计模式学习之工厂模式

    简单工厂模式 我直接上代码代码里有很详细的注解 //简单工厂模式 是由一个工厂对象决定创建出哪种产品 class Factory1 {publicstatic void main(String[] a ...

最新文章

  1. 又一位先驱陨落:伯特·萨瑟兰去世,他参与创造互联网、Java、图形界面PC、微处理器,也是明智的实验室领袖...
  2. python在读写文件之前需要创建文件对象-Python对象序列化写入文件对象
  3. 面试了100个运营,发现具备这些思维的人才能走的更远
  4. leetcode 637. Average of Levels in Binary Tree | 637. 二叉树的层平均值(Java)
  5. cookie、session、sessionid 与jsessionid
  6. TCP/IP协议详解 卷一(阅读指导)
  7. 连续整数的和(51Nod-1138)
  8. python简单代码-手把手教你用Python创建简单的神经网络(附代码)
  9. 深度学习DeBug小笔记(一)——visdom服务启动时提示Downloading scripts, this may take a little while解决办法
  10. 简易云在线人事管理系统
  11. Linux自学之旅-安装篇(挂载)
  12. python文本风格_Python风格规范-FYI
  13. 服务器安装版u盘如何制作,U盘怎么安装原版Windows server 2016?
  14. 卖家/消费者如何在淘宝申请人工客服
  15. darknet cpp weights模型转换成ONNX模型
  16. 参考线--深入了解字体
  17. pytorch to_device遇到数据迁移不成功的问题
  18. python自动控制程序_使用 Python 自动执行 ANSYS APDL
  19. 数据库视图的基本概念及作用
  20. web服务器项目背景,项目18-Web服务器配置与管理

热门文章

  1. Wi-Fi 7来了!小米13系列和万兆路由器再提速
  2. 爱国者u盘linux驱动,爱国者u盘驱动下载-aigo爱国者u盘驱动下载电脑版-121软件园...
  3. web页面 新消息提示音
  4. 惊爆:最简单绕过WGA验证工具正版验证的方法
  5. 和互联网行业技术大咖1V1免费聊?机会难得哦~
  6. 【百度地图(极度真实版)---HTML实现(附 效果+源代码)】
  7. 思科网络工程师自测题答案篇--【问题分析与发散思考】-晁海江-专题视频课程...
  8. Presto RBO 之 算子列裁剪
  9. 周志华《机器学习》3.5答案-编程实现线性判别分析,并给出西瓜数据集3.0α上的结果
  10. signature=b0e0b3f7d0e5b4c008c798d95174dc8e,高清剧场