理解设计模式之工厂模式

本贴最后更新于 2266 天前,其中的信息可能已经事过景迁

什么是工厂模式?

  上一篇文章写了关于创建模式之一的单例模式,这篇依然是关于创建模式的,最常用的模式之一,工厂模式。那么到底什么是工厂模式?理解工厂模式的概念很容易,光看工厂两个字就知道了,就是用来生产东西的,工厂模式,可以理解为专门用于生产对象的类,这个类不做其他的,就是生产对象。那么为什么会出现这个模式?我们直接 new 一个对象不就好了吗?还这么麻烦要专门用一个类来干这个事,不是多此一举么?其实不然,工厂模式提倡了“面向接口”编程的思想,将具体对象的创建跟业务代码解耦,让业务不用关心对象是如何产生的,只需要调用业务对象的接口即可。你想想,如果是 new 一个对象,然后再初始化这个对象的一些属性,万一哪天对象发生了变化,增加了一个需要初始化的属性,岂不是所有 new 这个对象的地方都会改一遍?这明显违背了“开闭原则”。因此工厂模式的出现,正是解决对象创建跟业务代码紧耦合这个问题。

工厂模式分类

  工厂模式就是工厂模式,干嘛还要分类呢?初学者可能对这个问题比较疑惑。为啥要分一下类呢?因为工厂这个东西,会随着产品的复杂程度而变化,跟现实世界中的一样,一个简单的工厂流水线不可能生产出种类繁多又很复杂的产品,那么随着产品的变化,工厂的实现也会跟着变化。根据以往查看过的资料来看,工厂模式一共分为三类:简单工厂、工厂方法、抽象工厂。看了一下网上的资料,与以往的总结,简单描述一下自己对这三类工厂实现的理解(只讲原理,不贴代码)。
  简单工厂 Simple Factory
  简单工厂,为啥要叫简单工厂?因为简单。我这个工厂只生产一个种类的产品,不生产其他东西,那么这个工厂就是简单工厂。例如假如你开了一个面食厂,专门做包子,生产肉包、菜包和豆沙包(如果你想买馒头,不好意思,到隔壁老王的馒头店去)。结合 UML 类图理解一下:
png
  工厂方法 Factory Method
  上面是简单工厂,只能生产一些简单的东西,我就生产这类产品,还是拿面食厂举例,面食厂开张后,生意好了,吃得人越来越多,时间久了大家觉得一个师傅做出来的口味始终是一个味道(想想你们在公司食堂吃了一年的饭菜),这时候突然有人提议,要吃换个口味的包子,但是包子还是肉包、菜包和豆沙包,这个时候怎么办?那么就轮到工厂方法出马了,工厂方法模式生产的产品还是那几样,但是实现者却不一样,实现的产品也不一样,拿面食店举例,假如之前是请老干妈做的包子,那么现在又请了一个老干爹,做口味不一样的包子。结合 UML 类图理解一下:
png
  虽然都是肉包子,但是老干妈的肉包子跟老干爹的肉包子是不一样的口味,因此工厂方法,适合同款产品有多种不同实现的场景。最简单的应用场景如数据库驱动,数据库驱动标准接口是
java.sql.Driver,Driver 生产 java.sql.Connection 对象。实现 java.sql.Driver 接口的驱动程序有跟多,例如 MySQL 的驱动与 Oracle 的驱动,两者生产的 Connection 对象也分别是基于 MySQL 数据库的实现和 Oracle 数据库的实现,但是对于业务开发人员来说,并不用关心到底是 Connection 是什么实现,我只需要定义好对应数据库的驱动程序即可。
  抽象工厂 Abstract Factory
  抽象工厂是在工厂方法之上的又一次扩展,随着产品的复杂度提高,工厂方法以及不能适应更多产品的生产,拿面食工厂举例,时间久了,大家对面食的种类产生了疑惑,为啥没有馒头?要求面食工厂能生产馒头,那么好,现在有两位师傅,一个是老干妈,一个是老干爹,从现在开始让他们生产馒头,我们工厂现在的产品种类有包子和馒头(哪天说不定还有花卷),在这种支持产品种类会有扩展的场景,就需要抽象工厂设计模式来搞定了。集合 UML 类图理解一下抽象工厂:
png
抽象工厂适合产品种类会扩展的场景,但是这种模式也有弊端,在进行产品种类扩展的同时,也会去修改已有的工厂类,添加新的产品生产接口,这个违背了开闭原则,因此要谨慎使用。

  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    3195 引用 • 8215 回帖
  • 设计模式

    设计模式(Design pattern)代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人员经过相当长的一段时间的试验和错误总结出来的。

    200 引用 • 120 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...

推荐标签 标签

  • Latke

    Latke 是一款以 JSON 为主的 Java Web 框架。

    71 引用 • 535 回帖 • 824 关注
  • IBM

    IBM(国际商业机器公司)或万国商业机器公司,简称 IBM(International Business Machines Corporation),总公司在纽约州阿蒙克市。1911 年托马斯·沃森创立于美国,是全球最大的信息技术和业务解决方案公司,拥有全球雇员 30 多万人,业务遍及 160 多个国家和地区。

    17 引用 • 53 回帖 • 149 关注
  • Flutter

    Flutter 是谷歌的移动 UI 框架,可以快速在 iOS 和 Android 上构建高质量的原生用户界面。 Flutter 可以与现有的代码一起工作,它正在被越来越多的开发者和组织使用,并且 Flutter 是完全免费、开源的。

    39 引用 • 92 回帖 • 2 关注
  • OAuth

    OAuth 协议为用户资源的授权提供了一个安全的、开放而又简易的标准。与以往的授权方式不同之处是 oAuth 的授权不会使第三方触及到用户的帐号信息(如用户名与密码),即第三方无需使用用户的用户名与密码就可以申请获得该用户资源的授权,因此 oAuth 是安全的。oAuth 是 Open Authorization 的简写。

    36 引用 • 103 回帖 • 29 关注
  • LeetCode

    LeetCode(力扣)是一个全球极客挚爱的高质量技术成长平台,想要学习和提升专业能力从这里开始,充足技术干货等你来啃,轻松拿下 Dream Offer!

    209 引用 • 72 回帖 • 1 关注
  • FlowUs

    FlowUs.息流 个人及团队的新一代生产力工具。

    让复杂的信息管理更轻松、自由、充满创意。

    1 引用 • 1 关注
  • 游戏

    沉迷游戏伤身,强撸灰飞烟灭。

    181 引用 • 821 回帖
  • CloudFoundry

    Cloud Foundry 是 VMware 推出的业界第一个开源 PaaS 云平台,它支持多种框架、语言、运行时环境、云平台及应用服务,使开发人员能够在几秒钟内进行应用程序的部署和扩展,无需担心任何基础架构的问题。

    5 引用 • 18 回帖 • 177 关注
  • DevOps

    DevOps(Development 和 Operations 的组合词)是一组过程、方法与系统的统称,用于促进开发(应用程序/软件工程)、技术运营和质量保障(QA)部门之间的沟通、协作与整合。

    57 引用 • 25 回帖 • 10 关注
  • golang

    Go 语言是 Google 推出的一种全新的编程语言,可以在不损失应用程序性能的情况下降低代码的复杂性。谷歌首席软件工程师罗布派克(Rob Pike)说:我们之所以开发 Go,是因为过去 10 多年间软件开发的难度令人沮丧。Go 是谷歌 2009 发布的第二款编程语言。

    498 引用 • 1395 回帖 • 254 关注
  • 快应用

    快应用 是基于手机硬件平台的新型应用形态;标准是由主流手机厂商组成的快应用联盟联合制定;快应用标准的诞生将在研发接口、能力接入、开发者服务等层面建设标准平台;以平台化的生态模式对个人开发者和企业开发者全品类开放。

    15 引用 • 127 回帖
  • Notion

    Notion - The all-in-one workspace for your notes, tasks, wikis, and databases.

    10 引用 • 76 回帖
  • 招聘

    哪里都缺人,哪里都不缺人。

    189 引用 • 1057 回帖
  • 分享

    有什么新发现就分享给大家吧!

    247 引用 • 1794 回帖 • 3 关注
  • Sandbox

    如果帖子标签含有 Sandbox ,则该帖子会被视为“测试帖”,主要用于测试社区功能,排查 bug 等,该标签下内容不定期进行清理。

    431 引用 • 1250 回帖 • 599 关注
  • Vue.js

    Vue.js(读音 /vju ː/,类似于 view)是一个构建数据驱动的 Web 界面库。Vue.js 的目标是通过尽可能简单的 API 实现响应的数据绑定和组合的视图组件。

    267 引用 • 666 回帖 • 2 关注
  • Node.js

    Node.js 是一个基于 Chrome JavaScript 运行时建立的平台, 用于方便地搭建响应速度快、易于扩展的网络应用。Node.js 使用事件驱动, 非阻塞 I/O 模型而得以轻量和高效。

    139 引用 • 269 回帖
  • Ant-Design

    Ant Design 是服务于企业级产品的设计体系,基于确定和自然的设计价值观上的模块化解决方案,让设计者和开发者专注于更好的用户体验。

    17 引用 • 23 回帖 • 1 关注
  • BookxNote

    BookxNote 是一款全新的电子书学习工具,助力您的学习与思考,让您的大脑更高效的记忆。

    笔记整理交给我,一心只读圣贤书。

    1 引用 • 1 回帖 • 1 关注
  • TensorFlow

    TensorFlow 是一个采用数据流图(data flow graphs),用于数值计算的开源软件库。节点(Nodes)在图中表示数学操作,图中的线(edges)则表示在节点间相互联系的多维数据数组,即张量(tensor)。

    20 引用 • 19 回帖
  • Laravel

    Laravel 是一套简洁、优雅的 PHP Web 开发框架。它采用 MVC 设计,是一款崇尚开发效率的全栈框架。

    20 引用 • 23 回帖 • 740 关注
  • RemNote
    2 引用 • 16 回帖 • 8 关注
  • Quicker

    Quicker 您的指尖工具箱!操作更少,收获更多!

    36 引用 • 155 回帖
  • MyBatis

    MyBatis 本是 Apache 软件基金会 的一个开源项目 iBatis,2010 年这个项目由 Apache 软件基金会迁移到了 google code,并且改名为 MyBatis ,2013 年 11 月再次迁移到了 GitHub。

    173 引用 • 414 回帖 • 368 关注
  • 电影

    这是一个不能说的秘密。

    122 引用 • 608 回帖 • 1 关注
  • VirtualBox

    VirtualBox 是一款开源虚拟机软件,最早由德国 Innotek 公司开发,由 Sun Microsystems 公司出品的软件,使用 Qt 编写,在 Sun 被 Oracle 收购后正式更名成 Oracle VM VirtualBox。

    10 引用 • 2 回帖 • 15 关注
  • HHKB

    HHKB 是富士通的 Happy Hacking 系列电容键盘。电容键盘即无接点静电电容式键盘(Capacitive Keyboard)。

    5 引用 • 74 回帖 • 495 关注