前言

这篇博客将包括两种设计模式,一种是工厂模式,一种是抽象工厂模式。不管是哪一种设计模式,本质上在解决的问题是对象创建的问题。工厂,可以是简简单单的一个函数,也可以是一个有具体实现的类,也可以是一个抽象的类。它们共同的特点都是在创建对象。工厂,根据函数输入,或者自身的类型,决定创建抽象类的一个/一族子类对象。

变的是什么呢?对象的创建
不变的是什么呢?总有一个对象要被创建出来:工厂方法的调用

简单工厂

简单工厂往往就是一个函数,当然这个函数需要一个类承载它。简单工厂的这个函数,输入是创建类需要的信息,输出是一个抽象类。函数内部是根据信息去决定创建哪一个抽象类的子类。

工厂模式

在工厂模式中,有一个抽象的工厂类,这个类定义了创建对象的抽象方法,由具体的工厂去实现如何创建对象。有一个抽象的Product类,这个Product类提供了一些抽象方法,提供给Product的使用者调用,具体实现由子类来完成。

下图只是工厂方法的一种诠释,核心在于工厂方法。当然工厂类不一定需要productDoSomething()方法,在要使用这个Product的地方的时候,调用工厂类的createProduct()返回一个对象也是可以的。

分析

当一个类A依赖另一个抽象类B的时候,需要根据一些信息去创建B的子类对象,每次增加了新的B的子类,都要去"修改"A中创建子类的代码。于是,为了将变的部分分离,将创建子类对象这一变的部分抽取出来,形成一个抽象的createXXX方法。这样,当增加B的子类的时候,如果需要使用,就去"扩展"A,实现createXXX,不需要改动A和B。

这个模式符合开闭原则,并且将A不再需要了解B的具体子类。

代码分析

这里分析[4]中提到的,iterator()是一个工厂方法,它的UML图如下,以下列出来的仅仅是冰山一角。容器的种类那么多,对应的容器的迭代器也很多。那么这么多的容器和迭代器该如何正确管理呢?答案还是:对扩展开放,对修改封闭。

所有的可迭代的容器去实现Iterable中iterator()方法,这个方法让每个容器具体的去创建一个迭代器类。在ArrayList实现了一个内部类Itr,这个Itr就是ArrayList的实现了Iterator接口的迭代器。其他的可迭代的类,实现iterator()的接口类似如此。

抽象工厂

抽象工厂模式和工厂模式的区别在于抽象Product类的规模。工厂模式,解决的是一个Product类。抽象工厂模式,解决的是一族Product类。这一族类是有关联的,它们之间的合作需要来自同一个类。

抽象工厂的一个应用场景是GUI组件。GUI的按钮,文本,布局,容器等,在各个平台上的实现是不一样的,那么可以对每个平台创建一个具体的工厂,来解决GUI组件的创建。一旦工厂被创建出来,工厂的使用者不需要关心创建出来的组件之间是否兼容,因为只要它们来自同一个工厂,都默认是兼容的。

参考

1,https://refactoring.guru/design-patterns
2,https://www.runoob.com/design-pattern/design-pattern-intro.html
3,Head First设计模式
4,Android源代码设计模式解析与实战
5,https://stackoverflow.com/questions/1673841/examples-of-gof-design-patterns-in-javas-core-libraries

【设计模式】Factory的更多相关文章

  1. C++设计模式-Factory工厂模式

    Factory1.定义创建对象的接口,封装对象的创建2.将实际创建工作延迟到子类中,例如,类A中药使用类B,B是抽象父类,但是在类A中不知道具体要实例化哪一个B的子类,但是在类A的子类D中是可以知道的 ...

  2. 工厂设计模式 Factory

    Factory 主要用来实例化有共同接口的类,工厂模式可以动态决定应该实例化那一个类. 例如:汽车销售商场 该模式将创建对象的过程放在了一个静态方法中来实现.在实际编程中,如果需要大量的创建对象,该模 ...

  3. 使用C# (.NET Core) 实现简单工厂(Simple Factory) 和工厂方法设计模式 (Factory Method Pattern)

    本文源自深入浅出设计模式. 只不过我是使用C#/.NET Core实现的例子. 前言 当你看见new这个关键字的时候, 就应该想到它是具体的实现. 这就是一个具体的类, 为了更灵活, 我们应该使用的是 ...

  4. 三种常见设计模式 - Factory

    创建型模型 一.简单工厂模式 靠 if else 或者 select case 等分支去控制不同对象的创建,难以维护 二.工厂方法模式  Factory 实现方式:将创建对象的方法定义成一个接口,通过 ...

  5. Java 设计模式实现 不错的引用

    这段时间有兴趣重新温习一下设计模式在Java中的实现,碰巧看到一个不错的设计模式总结,这里引用一下作为参考. 创建型模式: JAVA设计模式-Singleton JAVA设计模式-Factory JA ...

  6. Template Method 模板设计模式

    什么是模板设计模式 对于不了解的模板设计模式的来说,可以认为如同古代的造纸术一样,纸所以成型,取决于用了模板的形状,形状又由镂空的木板组成,而你想要造什么纸,又取决于你使用什么材料. 上面提到了两个关 ...

  7. [php]php设计模式 (总结)

    转载自[php]php设计模式 (总结) 传统的23种模式(没有区分简单工厂与抽象工厂) http://www.cnblogs.com/bluefrog/archive/2011/01/04/1925 ...

  8. Java设计模式从精通到入门五 抽象工厂方法模式

    定义 抽象工厂类为创建一组相关和相互依赖的对象提供一组接口,而无需指定一个具体的类. ​ 这里我得把工厂方法模式得定义拿出来做一下比较:定义一个创建对象的接口,由子类决定实例化哪一个类.工厂方法是一个 ...

  9. 《PHP设计模式大全》系列分享专栏

    <PHP设计模式大全>已整理成PDF文档,点击可直接下载至本地查阅https://www.webfalse.com/read/201739.html 文章 php设计模式介绍之编程惯用法第 ...

  10. 设计模式学习笔记(详细) - 七大原则、UML类图、23种设计模式

    目录 设计模式七大原则 UML类图 设计模式分类 单例模式 工厂设计模式 简单工厂模式 工厂方法模式(使用抽象类,多个is-a) 抽象工厂模式(使用接口,多个like-a) 原型模式 建造者模式 适配 ...

随机推荐

  1. 获取SpringCloud gateway响应的response的值,记录踩坑

    最近在做网关改造,想要通过Gateway过滤器获取ResponseBody的值,查看了网上的帖子和官网内容: 帖子:https://cloud.tencent.com/developer/articl ...

  2. 一文带你彻底理解Linux的各种终端类型及概念

    每天使用Linux每天都要接触到Bash,使用Bash时似乎永远都让人摸不着头脑的概念就是终端,坐在这台运行着Linux的机器的显示器前面,这个显示器就是终端的输出,而插在机器上的USB键盘或者PS/ ...

  3. .net core 发布IIS 出现Http 500错误

    首先再webconfig中设置stdoutLogEnabled="true",然后运行之后,到logs中查看登陆错误日志. 根据不同的错误进行解决: 我的错误是发布文件夹中缺少Dw ...

  4. 【day02】Xhtml

    一.HTML实体(HTML Entites) 1.HTML实体:W3C规定在浏览器看到的特殊符号必须用HTML实体  单引号(') ===== '  双引号(") ===== "  ...

  5. Node.js 获取本机Mac地址

    首先我们要先加载一个包用于获取mac地址 npm install getmac 加载完毕会在node_modules文件夹下发现一个getmac文件夹,我们把对应的路径加载到程序中 源码如下: var ...

  6. Codeforces Round #573 (Div. 2) Tokitsukaze and Mahjong 水题

    B. Tokitsukaze and Mahjong time limit per test1 second memory limit per test256 megabytes Tokitsukaz ...

  7. 前后端通信—webSocket(支持跨域)

    WebSocket 的介绍 WebSocket 是什么 WebSocket 是一种网络通信协议.RFC6455 定义了它的通信标准. WebSocket 是 HTML5 开始提供的一种在单个 TCP ...

  8. Vue 学习记录(一)-创建项目

    环境准备 node.js vue-cli 安装配置环境 1.下载node.js,使用默认配置安装 . 2.使用npm命令安装国内下载镜像(可选) cmd: npm install  -g  cnpm  ...

  9. 获取主机信息,网络信息AIP,getsockname,getpeername,getservbyname,getservbyport,inet_ntop,inet_pton

    获取主机信息 1.ip地址转换,主机字节序 <---> 网络字节序 #include <arpa/inet.h> int inet_pton(int af, const cha ...

  10. 微信小程序开发语音识别文字教程

    微信小程序开发语音识别文字教程 现在后台 添加插件 微信同声传译 然后app.json 加入插件 "plugins": { "WechatSI": { &quo ...