C++ | 设计模式
文章平均质量分 69
linolzhang
资深产品经理,系统架构师,PMP,PMI-ACP敏捷开发专家,个人主要研究领域为 AI、AR、3D Visualization。
展开
-
设计模式之21 - 策略模式Strategy
1.概述 在软件开发中也常常遇到类似的情况,实现某一个功能有多种算法或者策略,我们可以根据环境或者条件的不同选择不同的算法或者策略来完成该功能。如查找、排序等,一种常用的方法是硬编码(Hard Coding)在一个类中,如需要提供多种查找算法,可以将这些算法写到一个类中,在该类中提供多个方法,每一个方法对应一个具体的查找算法;当然也可以将这些查找算法封装在一个统一的方法中转载 2017-01-13 20:21:04 · 470 阅读 · 0 评论 -
设计模式之3 - 工厂方法Factory Method
工厂方法模式 又称为多态工厂模式,注意这里面的多态,意义在于定义一个创建产品对象的接口,基类本身不去创建对象,而是交给其子类或者是其实现类去创建。 通过上图可以看到,IFactory作为基类,定义了createProduct 方法,而子类Factory通过继承实现不同的createProduct方法,这就是 工厂方法的概念,比如说我们有多个子类工厂(Factory1、Fa原创 2017-01-12 22:58:17 · 459 阅读 · 0 评论 -
设计模式之4 - 原型模式Proto Type
原型模式 核心价值在于复制(clone接口),调用类通过调用原型的 clone接口,生成原型类的一个新的实例。 原型模式被用在对象的频繁拷贝上,其作用与拷贝构造函数类似(Clone也用来屏蔽浅拷贝和深拷贝),主要有两种应用: 1)需要保存一份对象的拷贝 备份,作为数据留存; 2)克隆对象并设置改变后的部分属性。 我们来原创 2017-01-12 22:59:49 · 728 阅读 · 0 评论 -
设计模式之6 - 适配器Adapter
先说 适配器,比如 美标的转换插座、海淘电器用的110V到220V变压器、还有安卓到苹果的usb转换接头,这些都是非常常见的适配器的案例。 Adapter模式将一个类的接口转换成另外一个接口。使得原本由于接口不兼容而无法使用的类可以被正常调用。 适配器模式 的类图如下: 其中 Target 为需要适配的目标接口,Adaptee是需要被适原创 2017-01-13 20:15:55 · 345 阅读 · 0 评论 -
设计模式之7 - 桥接模式Bridge
桥接模式 与上一节的Adapter模式类似,是 媒介模式的一种。 桥接模式 的意义是将 抽象(Abstraction)与实现(Implementation)解耦,使得二者可以独立地变化。 通过 抽象类 Abstraction 对 实现类 Implementor 的调用,实现松耦合关系,Implementor负责实现核心功能,作为一个媒介调用方原创 2017-01-13 20:16:20 · 379 阅读 · 0 评论 -
设计模式之8 - 组合Composite
组合模式Composite 也称为 整体-部分 模式,用户可以通过一致的方式 整体调用。 组合模式特点可以概括为两点:1. 复杂对象对于简单对象的组合;2. 统一的对象接口,方便抽象的整体调用; 对于第一点,从学习面向对象开始,组合模式 就表达了最基本的封装的概念,这个意义上组合模式太简单,简单到和人要吃饭睡觉一样,或者说其本身并不算一种模式。原创 2017-01-13 20:16:51 · 353 阅读 · 0 评论 -
设计模式之9 - 装饰模式Decorator
我们经常会遇到这种问题,当一个类出现非常多的选择,比如 咖啡,要加 糖、抹茶、香草、牛奶……,那么多调味品,在这种情况下,考虑通过继承的方式是否合理?你会得到 很多种咖啡类,牛奶咖啡、抹茶咖啡、牛奶椰蓉咖啡、香草黑糖咖啡、曲奇巧克力蛋奶咖啡……,好像很不靠谱对吧? 发现了 上面的 子类爆炸问题 后,你可能会问,我需要定义那么多的子类吗? 咖啡就是咖啡,其他的只是酌料而已。原创 2017-01-13 20:17:06 · 358 阅读 · 0 评论 -
设计模式之10 - 门面模式Facade
门面模式 又称为 外观模式,是我们比较常用的模式之一,主要应用在于:1. 为一个复杂子系统提供一个简单接口,提高子系统的独立性 并简化外部的调用;2. 定义系统每一层的入口,有助于模块清晰化; 如上图所示,不管模块复杂度如何,只需要定义出来一套 调用接口即可,其模块具体的内部实现一概不管,在分组开发模式下,这种思路尤为重要,保证模块间的独立性和解耦合 是代原创 2017-01-13 20:17:27 · 379 阅读 · 0 评论 -
设计模式之11 - 享元模式FlyWeight
享元模式 是结构性模式中一种非常有用的模式,其特点在于 复用内存中已存在的对象,从而降低创建对象的开销。 这在系统中存在大量的 细粒度对象的情况下非常有用,比如 一篇英文文稿,里面的词成千上万,但是对应的英文字符只有26个,再加上10个数字,不考虑标点和其它特殊字符的情况下,只有36个对象。 这就是 享元,共享的元素。 对于上面的例子,内存中只原创 2017-01-13 20:17:44 · 497 阅读 · 0 评论 -
设计模式之12 - 代理模式Proxy
代理模式 比较简单,生活中有很多这样的例子,比如 有人在 天猫 上销售苹果手机,这个店铺就是苹果手机的一个代理;如果你想访问一个国外的网站,可能需要通过一个VPN代理来中转;某天犯懒,你通过百度点了外卖;还有满大街的房屋中介 等等,这些都是代理的例子。 先来看一下类结构图: 真实对象 与 代理类对象继承自统一接口,客户通过接口访问 代理Proxy,Pro原创 2017-01-13 20:18:03 · 662 阅读 · 0 评论 -
设计模式之13 - 责任链模式Chain Of Responsibility
条件判断 在编程中是应用最广的,他决定了程序的下一步应该怎么执行。我们来看下面一段代码:// 条件判断string strType = "";if(age<3) strType = "未入学";else if(age<6) strType = "幼儿园";else if(age<12) strType = "小学";else if(age<15)原创 2017-01-13 20:18:24 · 422 阅读 · 0 评论 -
设计模式之14 - 命令模式Command
Command是我们最常用的模式之一,主要用在 撤消/重做功能Undo | Redo,其中有代表的是二维/三维的图形操作,它为用户提供了必要的,可修改的操作接口,大大提高了软件的灵活性。Undo | Redo机制一般需要借助堆栈(或者队列,链表)等数据结构,通过记录每一步的操作来实现。 图形操作一般是通过图元属性的更改完成(比如move),这种操作称为可逆操作,只需要记录改变原创 2017-01-13 20:18:37 · 474 阅读 · 0 评论 -
设计模式之17 - 中介者模式Mediator
觥筹交错的2016,看惯了帝都的繁华,也习惯了帝都的房价,隔三差五接到一个电话,问问是谁打来的呢?没错,中介。 这是一个伟大的职业,解决了数百万人的就业问题,当然在代码设计中也不例外。 中介者模式 定义为 通过一个封装对象来处理多个对象之间的复杂交互,从而实现模块的解耦。 从图上能够看到,中介者模式 将多个模块之间复杂的交互和调用独立出原创 2017-01-13 20:19:54 · 391 阅读 · 0 评论 -
设计模式之18 - 备忘录模式Memento
有时候我们需要记录一个对象的状态,用于该对象在某些状况下的恢复,这种模式 我们称之为 备忘录模式。 就像你录一段 婚礼视频,写一篇日记 是一样的, 备忘录模式 类结构图定义如下:发起人(Originator):需要备份的对象,将自身的属性信息拷贝到一个 备忘录对象,并能够通过备忘录中的属性信息 进行恢复;备忘录(Memento):保存发起人状态,提供set,get原创 2017-01-13 20:20:19 · 429 阅读 · 0 评论 -
设计模式之20 - 状态模式State
在面向对象的思想下,经常会遇到这种这种情况,同一个对象在不同 状态下的表现是不一样的。 比如 一个人情绪的低落和高昂,甚至吃了兴奋剂,他竞技时跑步的速度肯定是不一样的。 同样你的空调 包含 制冷、制热、送风、除湿 等多个模式,每种模式下其属性都不同。 看明白了吗?这就是 状态模式,状态模式 允许一个对象在其内部状态改变的时候改变其行为。原创 2017-01-13 20:20:49 · 523 阅读 · 0 评论 -
设计模式之22 - 模板方法Template method
模板 是一个通俗的概念定义,PPT模板、Word模板、Excel模板,你能接触的模板有很多,模板其实就是一个 Example、一个框架,你根据这个例子去具体实现。 模板方法 的概念与此类似,在 抽象类中定义 算法的骨架,将具体内容 延迟到子类实现。 上面的这个图说明的比较清晰,我们通过代码再来看一下:class AbstractClass{原创 2017-01-13 20:21:25 · 443 阅读 · 0 评论 -
设计模式之23 - 访问者模式Visitor
访问者模式 属于23种设计模式里面 比较复杂的一种模式,访问者模式就是表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。 说白了 就是被访问者不需要改变,访问者通过继承抽象类操作 来定义对象的访问。抽象访问者(Visitor):声明了一个或者多个访问操作,形成所有的具体元素角色必须实现的接口。具体访问者(原创 2017-01-13 20:21:50 · 590 阅读 · 0 评论 -
C++基础学习之7 - 与C程序对话
C++当初设计该语言的初衷是 “C”扩展,所以C++一般被认为是C的超集,但“这并不意味着C++兼容C语言的所有东西”。C++保留了一部分过程式语言的特点,大部分的C代码可以很轻易地在C++中正确编译,但仍有少数差异,导致某些有效的C代码在C++中无法通过编译。因此,从C到C++,我们要因为这些差异而做出一些改变,我们应当熟悉这些差异,使用原有的丰富的C库为现在的C++工程更好地服务。那么在C++原创 2017-01-12 22:26:56 · 648 阅读 · 0 评论 -
设计模式之2 - 建造模式Builder
建造者模式 源自于复杂对象的构造过程,比如我们要建造一座房子,或者建造一辆车,Builder模式包含的角色包括: Director(Designer):指导者(或者 设计者) Builder:建造者 Product:产品 这里我们不再强调产品的概念,以房子为例来解析Builder模式的过程:原创 2017-01-12 22:56:51 · 401 阅读 · 0 评论 -
设计模式之1 - 抽象工厂Abstract Factory
工厂模式整体上是一个系列,建议 大家先看完后面的工厂方法模式,再回过头来看本章。 抽象工厂模式 是一种 创建类模式,和Factory Method类似,我们不去解释这个概念,网上能搜到的解释都很绕,越看越茫然,我们只去抓住其核心点。 核心就在于抽象,比如对于下面的用例,Factory类本身定义了两个方法,CreateProductA(衣服) 和 CreatePr原创 2017-01-12 22:55:33 · 478 阅读 · 0 评论 -
C++基础学习之16 - 多线程与互斥锁
熟悉Linux的童鞋都对多进程比较熟,Linux下的 fork也有很多教程介绍,但这不是我们本节的重点,我们在这里主要讲的是多线程。 相对于进程来讲,线程 是一个轻量级的概念,一个进程包含多个线程(至少1个)。 线程有自己的堆栈和局部变量,但没有内存空间,而是共享进程的内存空间。 这种共享内存机制 优点在于通过数据共享的快速访问,同样这种机制原创 2017-01-12 22:50:11 · 954 阅读 · 0 评论 -
设计模式之16 - 迭代器模式Itertor
1. 迭代器模式(Iterator Pattern)的定义(1)定义:提供一种方法顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示。 ①迭代器迭代的是具体的聚合对象(如数组和链表等),它围绕的是“访问”做文章。 ②可用不同的遍历策略来遍历聚合,比如是否需要过滤 ③为不同聚合结构提供统一的迭代接口,也就是说通过一个迭代接口可以访问不同的聚合结构,转载 2017-01-13 20:19:34 · 1718 阅读 · 1 评论 -
设计模式之15 - 解释器模式Interpreter
1. 解释器模式(Interpreter Pattern)的定义(1)定义 给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。 ①文法:即语法规则。在解释器模式中每一个语法都将对应一个解释器对象,用来处理相应的语法规则。它对于扩展、改变文法以及增加新的文法规则都很方便。 ②解释器模式描述了如何为简单的语言定义一个文转载 2017-01-13 20:19:06 · 1173 阅读 · 0 评论 -
设计模式之5 - 单例模式Singleton
单例模式 是一种创建类型的模式,通过隐藏构造和析构函数,实现在内存中仅有一个对象 的目的。 Singleton的这种实现方式是非常有价值的,在多个模块或者多个线程中进行访问,可以不需要传递对象或者指针,通过引入头文件即可实现在不同模块解耦。 先来看Singleton的代码实现:#ifndef _SINGLETON_H_#define _SI原创 2017-01-13 20:15:04 · 513 阅读 · 0 评论 -
C++基础学习之1 - 指针与引用
指针和引用 是困扰初学者的问题之一,我们知道,指针和引用 都能够指向一个对象(&对该对象进行操作),那么他们之间有什么区别呢? 我们先来看定义:指针:指针是一个特殊的变量,这个变量指向一个内存地址,即对象存储空间的首地址;引用:所指向对象的一个别名,与直接访问对象的方式一致; ok,看上去有点类似,也有些差别,我们通过代码示例来看:char *p1原创 2017-01-12 22:11:32 · 1113 阅读 · 0 评论 -
设计模式之19 - 观察者模式Observer
观察者模式(Observer)又称 订阅者模式(Subscriber),是一个发布者对应多个观察者,就像 微博、邮件订阅一样,只有订阅该新闻的用户才能够收取到该信息,类图定义: 发布者(Publisher)内部保存了一个观察者对象列表(Observer),当发布者属性发生变化时,调用notify通知观察者,提示信息变化。 模式的实现比较简单,我们定义原创 2017-01-13 20:20:34 · 421 阅读 · 0 评论 -
C++基础学习之14 - 再谈指针
前面已经讲过C++指针的概念,指针是一个特殊变量,里面保存了一个内存地址。 那么指针本身占了多大内存呢? 在32位平台上是 32位(4字节),在64位平台上就是 64 位。 我们通过代码来看一下指针的寻址方式。int a[5] = { 1,2,3,4,5 }; int *p = a; for(i=0;i<5;i++) { (*p)原创 2017-01-12 22:46:53 · 332 阅读 · 0 评论 -
C++基础学习之12 - 测试驱动开发
测试驱动开发,英文全称 Test-Driven Development,简称TDD,是一种不同于传统软件开发流程的新型的开发方法。它要求在编写某个功能的代码之前先编写测试代码,然后只编写使测试通过的功能代码,通过测试来推动整个开发的进行。这有助于编写简洁可用和高质量的代码,并加速开发过程。 测试驱动开发的基本过程如下:1. 快速新增一个测试;2. 运行所有的测试(有时原创 2017-01-12 22:41:51 · 704 阅读 · 0 评论 -
C++基础学习之11 - 初谈代码风格
什么样的代码格式是正确的?相信这个问题很难回答,每个人都有自己的习惯,作者就自己对于代码风格的理解整理如下:1. 优秀的代码必须足够简洁,用最少的代码实现最多的功能,不冗余;2. 良好的代码风格是易读的,包括良好的命名和一定的注释;3. 良好的代码风格必须是模块化的,功能单一且没有歧义; 我们来看以下一段代码: /** 可选项*/ const int T原创 2017-01-12 22:39:33 · 414 阅读 · 0 评论 -
C++基础学习之8 - 玩转DLL
在编程中,一个关键的问题就是 代码或模块复用,对于 模块复用 来说,LIB 和 DLL是最好的复用方式。 先来说静态库LIB,LIB库有两种可能:1. 在 Windows下是静态库(对应Linux下的 .a 文件);2. 对应 DLL 的入口或说明文件; 再来说 DLL,动态链接库(dynamic link library),是程序运行时用到的。原创 2017-01-12 22:31:42 · 819 阅读 · 0 评论 -
C++基础学习之5 - 认识C11新特征
C++11可以说是一个里程碑,针对C++本身的诸多问题,提供了优秀的思路和解决方案,作者从其中的几个点来介绍下C++11的几个典型特征。 概括新特性包括:auto类型推断、右值引用、智能指针、lambda表达式,另外还有 类型初始化列表、decltype、模板改进等,不在本节讨论范围内,感兴趣的同学请自行搜索。一. Auto类型推断 在C++11之前,与原创 2017-01-12 22:20:33 · 1071 阅读 · 0 评论 -
C++基础学习之2 - 内存对象模型
内存对象模型 是同学们在面试过程中经常会被问到的问题,一堆的 Sizeof 求答案,怎么破?听作者讲完本节,也许你会有个简单的认识,先说对于C++,其内存是如何存放的: 先说说C++的存储区,有4种类型,堆、栈、全局存储区、常量存储区。堆: 通过new来初始化,delete释放,一般是由程序员来创建和管理;栈: 栈 是指临时或局部变量的存放位置,一般由操作系统分配和释原创 2017-01-12 22:13:51 · 863 阅读 · 0 评论 -
C++基础学习之4 - 改善既有代码的设计
《重构,改善既有代码的设计》 是程序员必须的一本书,让现有的代码更加简洁,更加可靠永远是程序员要追求的目标,本节我们就结合书里的关键点进行说明,希望能够起到引入的效果。 作者从以下几个方面来介绍重构的内容:1. 代码风格 表现为 命名不能够表达实际意义; 可读性差 或 缺少注释;原创 2017-01-12 22:17:47 · 600 阅读 · 0 评论 -
C++基础学习之6 - STL解构
在C++编程里面,STL 是必不可少的,我们先列出来常用的几种容器: vector,list,Map,set,deque,queue+ vector vector是一种动态数组,其内容在内存中是连续存放的,正是由于这种特征,决定了vector 的代表特征: 随机访问速度很快,插入和删除效率较低。 其内存分配 是按照 1、2、4原创 2017-01-12 22:23:32 · 767 阅读 · 0 评论 -
C++基础学习之9 - MVC机制
MVC 是指 Model(模型)、View(视图)、Controller(控制器),旨在通过控制器 实现 数据(Model) 和 视图(View)的隔离。 这样做的优点在于能够实现有效的 模块解耦合,对于数据的变化能够通过 控制器 来进行响应和控制,而不需要修改视图。我们来看一个概念解释:1. 模型(Model):数据 模型是整个业务的核心,代表原创 2017-01-12 22:33:28 · 1460 阅读 · 0 评论 -
C++基础学习之10 - 插件开发
相信有过大型软件开发经验的人都会熟悉 插件开发(Plugin),这是一种轻内核的开发机制,通过独立的插件开发能够将不同的插件功能进行组合,从而实现灵活的即插即用。 目前支持插件功能的软件非常多,从Linux下的 Vim、Emacs、Sublime编辑器,到windows下的PS、3DMax、Maya、AutoCAD,再到 ArcGIS,几乎每个行业的软件都会有插件开发的影子,原创 2017-01-12 22:34:56 · 2641 阅读 · 1 评论 -
C++基础学习之13 - 可视化设计
讲到C++的可视化设计,一般都会想到 类图、流程图、交互图、部署图等,没错,UML设计是C++代码设计之前的必选项(当然对于产品经理们更关注UI,他们更愿意使用Axure),但是这些不是我们所关心的,本节我们要谈的是系统开发完成以后的设计图、文档。 这些内容可以通过UML给出吗?当然可以,但我相信大多数人无法做到这一点,因为在开发过程中大部分的设计早已面目全非,想保持同步的更原创 2017-01-12 22:45:02 · 3407 阅读 · 0 评论 -
C++基础学习之15 - 消息机制
提到进程间通信(IPC),你可能会想到很多种方式,比如:1)消息传递(管道、FIFO、消息队列);2)同步(互斥量、条件变量、读写锁、文件和写记录锁、信号量);3)共享内存(匿名的和具名的);4)远程过程调用(Solaris门和Sun RPC)。 没错,你有很多种选择,但提到消息,很多人第一印象就是 发送者(Sender)和 接收者(Receiver)。你原创 2017-01-12 22:49:03 · 1258 阅读 · 1 评论 -
C++基础学习之3 - 编译器
编译器(Compiler) 是指将一种语言 翻译为另一种语言的工具,对于C++来讲,是将我们写的代码语言 转换为二进制语言(EXE或者ELF),从而能够在Windows或者Linux下运行。 很多新同学可能对编译器并不敏感,直接用 IDE(VS、Eclipse)编译一下就可以了,没有感觉到编译器的存在,这其实就是一个问题,作者建议对于初学者尽量不要直接就用 IDE,先用 Linu原创 2017-01-12 22:15:26 · 769 阅读 · 0 评论