设计模式(三)创建型模式

前言

根据菜鸟教程的目录,我们首先来看看创建型模式。
创建型模式研究:

  1. 实际应用中通常有哪些不同的创建对象的场景;
  2. 在不同的场景下,如何更好地编写创建对象的代码。
  3. 主要研究构造函数。

下面分别对创建型模式下的各种具体模式进行讲解。


1. 工厂模式

先看例子: 工厂模式。

使用场景

某功能的使用者只和接口打交道,不关心如何实现。这种情况下,肯定有一个接口类,使用者使用接口;功能提供者继承并实现接口。这利用了C++的多态特性。

不好的做法

既然使用者只关心接口,那么没有必要把子类直接给使用者,没有必要让使用者在代码中直接new子类。如果这样做,会把不必要的信息暴露给使用者,增加了信息的耦合。试想,如果使用者在很多地方都new了子类,那么如果这些地方需要修改的话,怎么改?只能一个一个地方改,改完还需要编译,维护极其困难。

现成的方案 :工厂模式

工厂模式是指,针对某一功能接口,我们要新建一个工厂类,此工厂类将接口子类名称、接口子类的创建过程封装起来,只返回一个接口指针给接口的使用者。接口的实现类对使用者完全透明,高度解耦。这样可以方便地切换接口的具体实现,而不影响上层功能使用者。拿汽车打比方,不管工厂生产汽车的流程是什么,只要是汽车,它的驾驶方法(人机接口)都类似。

显而易见,工厂模式在使用者和实现者之间增加了一个封装层,这正印证了计算机行业中一句名言:

计算机科学领域的任何问题都可以通过增加一个间接的中间层来解决。

典型的例子是:Qt中的数据库模块就利用了工厂模式,封装了数据库的底层实现。在保持数据库用户接口不变的情况下,通过更换数据库驱动,可以实现数据库类型无缝切换。

不适用的情况
  • 如果只是一个单独工作的类,没有实现接口,就不需要用工厂模式。
  • 如果一个类创建的地方不多,只有一两次,那也没有必要用工厂模式。可以在创建次数增多的时候,再考虑做优化。
小心使用

在需求趋于稳定时使用,需求不稳定时,不要过度设计,否则设计很容易被推翻,白费力气。

本质

从设计模式的本质来看,工厂模式:

工厂模式,封装了子类对象的创建过程,隐藏了子类,实现了使用者和实现者解耦。


2. 抽象工厂模式

先看例子: 抽象工厂模式。

使用场景

由前面工厂模式可知,所有的“工厂”有一个共同点:每个工厂都会提供创建对象的函数。
既然所有工厂都实现了同一类功能,那么我们可以为工厂抽象出一个公共接口(虚基类),此接口定义了创建工厂子类的功能。
这种场景是否似曾相识?是的,工厂和工厂的功能接口构成了使用工厂模式的场景。即工厂本身也适用于工厂模式。
使用工厂模式来设计工厂,必然要写一个生产工厂的工厂。
生产工厂的工厂,返回值是工厂的抽象接口类,所以这种设计模式叫“抽象工厂模式”。其实,笔者觉得把这种设计模式叫做“工厂工厂模式”更容易理解。

不适用的情况

如果只有一个工厂就不要使用抽象工厂模式了,只有在工厂很多时,才使用抽象工厂模式。

小心使用

需求不稳定时,不要过度设计,一切都可能被推翻。
对于小的项目,不需要过度追求使用设计模式,架构的代码最好只占整个项目代码的一小部分,否则就是主次颠倒,给自己找麻烦。
对于大的项目,在需求较稳定的情况下,为了提高可维护性、扩展性,可以考虑使用设计模式。
另外,抽象工厂模式有一定的理解难度,要考虑你设计的代码,其他人是否能够读懂,简单易懂也是需要考虑的方面。

本质

所以,从设计模式的本质来看,

抽象工厂模式,封装了工厂的创建过程。


3. 单例模式

先看例子: 单例模式。

使用场景

上面的例子都是允许一个类被创建多次的。如果我们想要限制一个类只被创建一次,即只有一个全局可访问的实例(和C语言中的全局变量一样),例如应用程序对象,每个应用程序都应该只有一个应用程序对象。此时应该怎么编写代码呢?

答案还是封装。把不想暴露出来的信息藏起来,把必须暴露的信息暴露出来。单例模式把类的构造函数设置成private私有访问权限,限制外部无法通过new来创建实例。只能通过特定的接口来获取实例指针。需要提及的是,封装时需要考虑多线程安全的问题。

不适用的情况

当一个类需要有多个实例存在时,不使用单例模式。

本质

从设计模式的本质上看,

单例模式,提供了一种限制实例个数的封装方法,在项目中需要用到单例时,可以参考现成的方案。


4. 建造者模式

具体的例子和写法,可以参考菜鸟教程中的 建造者模式。

使用场景

建造者模式的典型使用场景是快餐店的套餐搭配模型。
套餐由若干个单个餐品组合而成。单个餐品又由不同的原材料构成。这种层层组合的树形对象关系的应用场景下,为了创建顶层的对象,需要先一层层的创建底层的对象,逐步向上,直到构造出根对象。
这种场景下,使用继承可以将同类的对象关联起来,使用组合可以将不同类型的对象组合起来。组合就是把不同对象放在一块内存中保存,作为一个整体使用。

不好的做法

完全使用继承来解决此类问题是非常不提倡的。设计模式理论中有一个原则是:“少用继承,多用组合”。因为继承是一种强耦合,组合是一种松散的耦合。耦合不利于适应需求变化,是项目中的一颗定时炸弹。

本质

从设计模式的本质上看,

建造者模式,提出了针对树形的对象关系结构、包含不同种类子对象的、复杂对象的创建方法。封装同类对象可以使用类继承,封装具体的子类实现,只暴露基类。封装不同类型的子对象,使用组合。

菜鸟教程中没有提及的一种设计模式是组合模式。具体内容可以参考:
第四节:组合模式和建筑者模式详解。

这里简单说明一下,组合模式和建造者模式比较像,也是遵循树形对象关系结构。和建造者模式相比,不同之处在于,子对象和父对象具有相同的类型。所以可以说,组合模式是简单的建造者模式。


5. 原型模式

具体的使用场合和实例,见原型模式。

原型模式,在实际使用时可能用得不多。用一句话描述其特点:

以现有对象为模板,克隆出新的对象。

这种克隆是一种内存中的复制行为,速度快,能充分利用已有对象的缓存数据,性能高。克隆出来的对象具有和原对象相同的属性和行为,可以用来帮助原对象处理一些事务。用一句动漫中的词汇来描述,“影分身”再合适不过了。

从设计模式的本质看,

原型模式,提出了使用创建对象副本,代替直接new类创建对象的一种方法。将对象的创建过程封装起来,用对象拷贝来代替,可以避免不必要的资源浪费。


下一篇,我们将介绍结构型模式。

本文原创首发于微信公众号Qt未来工程师。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/436977.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CSDN改版,找不到各种入口,链接放下面

https://mp.csdn.net/console/article?spm1010.2135.3001.5128 https://mp.csdn.net/console/column/allColumnList 分类管理 https://mp.csdn.net/console/article 文章管理 https://mp.csdn.net/console/upDetailed 资源管理 https://mp.csdn.net/editor/html?spm1011.…

python中pca算法_python实现PCA算法01

python实现PCA算法Software version: Python 2.7.12 |Anaconda 4.2.0 (64-bit)|法1. 编程一步一步实现法2. sklearn我们以定义函数的形式来一步一步进行1.1 导入模块:Numpy,Pandas# -*- coding: utf-8 -*-# Time : 2017/8/17 14:20# Author :…

设计模式(一)预备知识

前言 学习设计模式需要有面向对象编程的基础,要基本掌握一种面向对象的编程语言。关于面向对象编程思想,我们有另外一篇文章专门讲解:面向过程和面向对象的联系和区别。 知识点 虚函数 在类的成员函数定义中,形式上为定义为vir…

【转】GitHub 从单机到联机:玩转 Pull Request

最近在参与一个叫 Exercism 的项目,这是一个由 GitHub 生态工程师 Katrina Owen 发起的编程练习社区,提供了超过50门语言的练习。作为用户,你仅需使用命令行工具即可下载和提交练习,提交后还可以和社区中其他学习者交流讨论。 Exe…

android cmake 打印_Android使用CMAKE编译libjpeg

本文主要介绍使用 CMAKE 编译 libjpeg-turbo 类库,本文相关代码请在GitHub-TurboJpegSample 查看。libjpeg-turbo 附GitHub 地址,libjpeg-turbo 是个运用极其广泛的库,可以说,基本上电脑上手机上能见到的 JPEG 压缩的地方用的一般…

设计模式(四)结构型模式

前言 结构型设计模式,主要研究: 主要有哪些场景使用结构型设计模式;每种场景应该使用何种设计模式;以程序中的功能为核心,研究程序功能的组织结构。所以这一章,我们要把“功能结构”作为研究的核心。 下…

centos 删除crontab_centos下crontab的使用

4.cron文件语法:分 小时 日 月 星期 命令0-59 0-23 1-31 1-12 0-6 command (取值范围,0表示周日一般一行对应一个任务)5.记住几个特殊符号的含义:“*”代表取值范围内的数字,“/”代表”每”,“-”代表从某个数字到某个数字,“,”分开…

【转】GitHub客户端操作1--仓库相关操作github团队协作流程

1、创建仓库 点击“”,点击Create,然后填写Name为my,点击Create repository,即可创建一个my仓库 2、从本地仓库存放位置,添加test仓库到GitHub客户端 点击“”,点击Add,然后点击Browse,选择仓库存放位置&a…

音视频相关链接

开发库 FFmpeg FFmpeg官网 FFmpeg github 平台相关 DirectShow DirectShow简介 DirectShow官网

【转】GitHub客户端操作2--分支操作

简单分支操作 (1)创建新分支:my分支 备注:新创建的分支:my分支里面的内容是和master分支里面的内容是完全一样的。 (2)删除my分支 (3)修改my分支【在my分支上进行项目内…

uniapp动态修改样式_uniapp样式动态绑定

场景一:用户点击按钮后动态切换按钮选中样式(如图)已上线未开始//选择状态selectState(e){this.whichSelectede.currentTarget.dataset.state}.state-btn-content{//write your style.state-btn-selected{ ... }.state-btn-noselect{ ... }}注:需要注意的…

音视频工程师(初步)(一)音视频的基本概念

1. 前言 本文是音视频工程师系列的第一篇文章。 学习音视频的过程中发现,网络上高质量的音视频技术博客不是很多。具有代表性的是 雷神的 雷霄骅的CSDN博客 因为笔者是一名普通的软件开发人员,一向不喜欢高高在上或者晦涩难懂的理论,我们…

【转】GitHub客户端操作3--pull Request(拉请求)

一、参考说明 参考文章一:Github上提交代码(pullrequest) 网址: https://jingyan.baidu.com/article/358570f64dcdc2ce4724fc32.html 参考文章二:GitHub——Pull Request 网址:http://blog.csdn.net/u012325167/article/detai…

webstorm 内存溢出怎么弄_webstrom 内存溢出,软件崩溃卡死解决的方法

今天用gulp搭建了一个工程,准备做一个体育h5的项目,其中需要用到sass代码压缩,加版本号等功能.gulpfile.js和package.json都是已经写好的.我用CMD命令窗口cnpm安装node_modules依赖文件.当我安装完毕之后用webstrom打开时,第一件事先把node_modules排除忽略了.如下:然后我去编辑…

躺平也要看,2022年计算机相关考试汇总

1. 全国计算机专业资格考试(软考) 1.1 官网 全国官网:https://www.ruankao.org.cn/,从全国官网首页的底部可以直达各个省区的考试机构报名网站。 1.2 考试安排 软考一年两次。 场次报名时间考试时间上半年 预计报名时间在2月…

【转】GitHub上README.md教程

本文是转载文章,文章的来源:csdn博客 博主:果冻虾仁 文章: GitHub上README写法暨GFM语法解读 博文地址:https://blog.csdn.net/guodongxiaren/article/details/23690801 转载请保留原作者guodongxiaren的原文地址&…

python supervisor flask_supervisor配合uwsgi部署flask应用

这已经是第N次来部署flask应用了, 但是每次都花了不少时间在配置上面, 这里一次性记录下, 备个忘~写在前面其实使用uwsgi来部署flask应用在官网上已经有较为详细的 文档 了, 推荐先读一下.先解决一些问题:为何使用 uwsgi 来部署应用? 方便管理; 较为常见的部署方式; 可配置性较…

设计模式(五)行为型模式

前言 在上一篇结构型模式中,我们以功能为基本单位,研究了一些设计模式,用于实现功能转换、功能组合、功能封装等目的。 我们知道,面向对象编程有两个核心元素:对象、对象间通信协作。从面向对象的角度看,…

51单片机auxr寄存器_51—52系列单片机特殊功能寄存器一览表

P2.1P2.0RSTP3.0/RXDP3.1/TXDXTAL2XTAL1P3.2/INT0P3.3/INT1P3.4/T0P3.5/T1GNDVCCP1.7P1.6P1.5P1.4P1.3P1.2P1.1/AIN1P1.0/AIN0P3.7注:类似的还有Philips公司的87LPC64,20引脚8XC748/750/(751),24引脚8X749(752),28引脚8XC754&…

【转】WPF单位真的与分辨率无关吗?

转载自http://www.cnblogs.com/helloj2ee/archive/2009/04/21/1440709.htm WPF从发布之日起,一直将“分辨率无关(resolution independence)”作为其亮点,声称使用WPF制作的用户界面在轻巧的Ultra-Mobile PC的屏幕上和在50英寸的电视机上都能很好地显示。…