C++设计模式基础和模式设计基本原则
文章目录
- 1. 模式
- 2. 设计模式(Design pattern)
- 3. 设计模式的分类
- 4. 具体分类
- a. 创建型模式
- 1. 工厂方法模式(Factory Method Pattern)用意是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类中
- 2. 抽象工厂模式(Abstract Factory Pattern)的意图是提供一个创建一系列相关或者相互依赖的接口,而无需指定它们具体的类。
- 3. 建造者模式(Builder Pattern)的意图是将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。
- 4. 原型模式(Prototype Pattern)是用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
- 5. 单例模式(Singleton Pattern)是保证一个类仅有一个实例,并提供一个访问它的全局访问点。
- d. 结构型模式
- 6,代理模式(Proxy Pattern)就是为其他对象提供一种代理以控制对这个对象的访问。
- 7,装饰者模式(Decorator Pattern)动态的给一个对象添加一些额外的职责。就增加功能来说,此模式比生成子类更为灵活。
- 8,适配器模式(Adapter Pattern)是将一个类的接口转换成客户希望的另外一个接口。使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
- 9,桥接模式(Bridge Pattern)是将抽象部分与实际部分分离,使它们都可以独立的变化。
- 10,组合模式(Composite Pattern)是将对象组合成树形结构以表示“部分--整体”的层次结构。使得用户对单个对象和组合对象的使用具有一致性。
- 11,外观模式(Facade Pattern)是为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
- 12,享元模式(Flyweight Pattern)是以共享的方式高效的支持大量的细粒度的对象。
- c. 行为型模式
- 13,模板方法模式(Template Method Pattern)使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
- 14,命令模式(Command Pattern)是将一个请求封装为一个对象,从而使你可用不同的请求对客户端进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。
- 15,责任链模式(Chain of Responsibility Pattern),在该模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求,这使得系统可以在不影响客户端的情况下动态地重新组织链和分配责任。
- 16,策略模式(Strategy Pattern)就是准备一组算法,并将每一个算法封装起来,使得它们可以互换。
- 17,中介者模式(Mediator Pattern)就是定义一个中介对象来封装系列对象之间的交互。终结者使各个对象不需要显示的相互调用 ,从而使其耦合性松散,而且可以独立的改变他们之间的交互。
- 18,观察者模式(Observer Pattern)定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
- 19,备忘录模式(Memento Pattern)是在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。
- 20,访问者模式(Visitor Pattern)就是表示一个作用于某对象结构中的各元素的操作,它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。
- 21,状态模式(State Pattern)就是对象的行为,依赖于它所处的状态。
- 22,解释器模式(Interpreter Pattern)就是描述了如何为简单的语言定义一个语法,如何在该语言中表示一个句子,以及如何解释这些句子。
- 23,迭代器模式(Iterator Pattern)是提供了一种方法顺序来访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示。
- 5. 设计模式基本原则
- a. 开放封闭原则 (OCP,Open For Extension, Closed For Modification Principle)
- b. 单一职责原则 (SRP,Single Responsibility Principle)
- c. 依赖倒置原则 (DIP,Dependence Inversion Principle)
- d. 接口隔离原则 (ISP,Interface Segegation Principle)
- e. 里氏替换原则 (LSP, Liskov Substitution Principle)
- f. 优先使用组合而不是继承原则(CARP,Composite/Aggregate Reuse Principle)
- g. 迪米特法则(LOD,Law of Demeter) 最少原则
1. 模式
在一定环境中解决某一问题的方案,包括三个基本元素–(问题,解决方案,环境)。
即: 在一定环境下,用固定套路解决问题。
2. 设计模式(Design pattern)
是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代 码可靠性。 毫无疑问,设计模式于己于他人于系统都是多赢的;设计模式使代码编制真正工程化;
设计模式是软件工程的基石脉络,如同大厦的结构一样。
学习设计模式的意义
提高职业素养,关注学员在行业内的长期发展。
3. 设计模式的分类
Gang of Four的“Design Patterns: Elements of Resualbel Software”书将设计模式归纳为三大类型,共23种。
创建型模式 : 通常和对象的创建有关,涉及到对象实例化的方式。(共5种模式)
结构型模式: 描述的是如何组合类和对象以获得更大的结构。(共7种模式)
行为型模式: 用来对类或对象怎样交互和怎样分配职责进行描述。(共11种模式)
4. 具体分类
a. 创建型模式
用来处理对象的创建过程,主要包含以下5种设计模式:
1. 工厂方法模式(Factory Method Pattern)用意是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类中
2. 抽象工厂模式(Abstract Factory Pattern)的意图是提供一个创建一系列相关或者相互依赖的接口,而无需指定它们具体的类。
3. 建造者模式(Builder Pattern)的意图是将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。
4. 原型模式(Prototype Pattern)是用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
5. 单例模式(Singleton Pattern)是保证一个类仅有一个实例,并提供一个访问它的全局访问点。
d. 结构型模式
用来处理类或者对象的组合,主要包含以下7种设计模式:
6,代理模式(Proxy Pattern)就是为其他对象提供一种代理以控制对这个对象的访问。
7,装饰者模式(Decorator Pattern)动态的给一个对象添加一些额外的职责。就增加功能来说,此模式比生成子类更为灵活。
8,适配器模式(Adapter Pattern)是将一个类的接口转换成客户希望的另外一个接口。使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
9,桥接模式(Bridge Pattern)是将抽象部分与实际部分分离,使它们都可以独立的变化。
10,组合模式(Composite Pattern)是将对象组合成树形结构以表示“部分–整体”的层次结构。使得用户对单个对象和组合对象的使用具有一致性。
11,外观模式(Facade Pattern)是为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
12,享元模式(Flyweight Pattern)是以共享的方式高效的支持大量的细粒度的对象。
c. 行为型模式
用来对类或对象怎样交互和怎样分配职责进行描述,主要包含以下11种设计模式:
13,模板方法模式(Template Method Pattern)使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
14,命令模式(Command Pattern)是将一个请求封装为一个对象,从而使你可用不同的请求对客户端进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。
15,责任链模式(Chain of Responsibility Pattern),在该模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求,这使得系统可以在不影响客户端的情况下动态地重新组织链和分配责任。
16,策略模式(Strategy Pattern)就是准备一组算法,并将每一个算法封装起来,使得它们可以互换。
17,中介者模式(Mediator Pattern)就是定义一个中介对象来封装系列对象之间的交互。终结者使各个对象不需要显示的相互调用 ,从而使其耦合性松散,而且可以独立的改变他们之间的交互。
18,观察者模式(Observer Pattern)定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
19,备忘录模式(Memento Pattern)是在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。
20,访问者模式(Visitor Pattern)就是表示一个作用于某对象结构中的各元素的操作,它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。
21,状态模式(State Pattern)就是对象的行为,依赖于它所处的状态。
22,解释器模式(Interpreter Pattern)就是描述了如何为简单的语言定义一个语法,如何在该语言中表示一个句子,以及如何解释这些句子。
23,迭代器模式(Iterator Pattern)是提供了一种方法顺序来访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示。
5. 设计模式基本原则
最终目的:高内聚,低耦合
a. 开放封闭原则 (OCP,Open For Extension, Closed For Modification Principle)
类的改动是通过增加代码进行的,而不是修改源代码。
#include <iostream>
using namespace std;
/*
1. 开闭原则, 对扩展开放, 对修改关闭增加功能是通过代码实现, 而不是修改源代码例如下文的计算器, 每个功能都是单独的类, 这样在扩展功能时, 就可以做到不动源代码增加
*/// 反面案例
// 计算器的计算方法, 当扩展取余等扩展运算, 不能重写函数// 写一个抽象类
class AbstractCaculate{public:virtual void setOperatorNumber(int a, int b) = 0;virtual int getResult() = 0;
};class PlusCaculate : public AbstractCaculate{private:int mA, mB;
public:virtual void setOperatorNumber(int a, int b){this->mA = a;this->mB = b;}virtual int getResult(){return this->mA + this->mB;}
};class MultiCaculate : public AbstractCaculate{private:int mA, mB;
public:virtual void setOperatorNumber(int a, int b){this->mA = a;this->mB = b;} virtual int getResult(){return this->mA * this->mB;}
};// 如果需要给calculation增加功能, 只需要在下面在定义一个类, 实现新的功能即可int main(int argc, char const *argv[])
{AbstractCaculate* caculator = new PlusCaculate();caculator->setOperatorNumber(3,5);cout<< "res = "<<caculator->getResult()<<endl;delete caculator; // 注意每次新创建的new出来的对象, 一定要使用delete进行销毁return 0;
}
b. 单一职责原则 (SRP,Single Responsibility Principle)
类的职责要单一,对外只提供一种功能,而引起类变化的原因都应该只有一个。
c. 依赖倒置原则 (DIP,Dependence Inversion Principle)
依赖于抽象(接口),不要依赖具体的实现(类),也就是针对接口编程。
// 04_依赖倒转原则.cpp
#include <iostream>
using namespace std;// 银行业务
class AbstractWorker{public:virtual void doBussiness() = 0;
};
// 底层业务
class doSaveWorker: public AbstractWorker{public:virtual void doBussiness(){cout<<"存款业务.."<<endl;}
};
class doPayWorker: public AbstractWorker{public:virtual void doBussiness(){cout<<"付款业务.."<<endl;}
};class doTransferWorker: public AbstractWorker{public:virtual void doBussiness(){cout<<"转账业务"<<endl;}
};// 中层业务, 具体实现就简单了
void doNewBusiness(AbstractWorker* worker){worker->doBussiness();
}int main(int argc, char const *argv[])
{// 类似于多态, 父类指向子类AbstractWorker* worker = new doTransferWorker();doNewBusiness(worker);delete worker; // 注意一定要把自己new的对象给delete了return 0;
}
d. 接口隔离原则 (ISP,Interface Segegation Principle)
不应该强迫客户的程序依赖他们不需要的接口方法。一个接口应该只提供一种对外功能,不应该把所有操作都封装到一个接口中去。
下面的代码都是遵循这种接口隔离原则进行编写的
e. 里氏替换原则 (LSP, Liskov Substitution Principle)
任何抽象类出现的地方都可以用他的实现类进行替换。实际就是虚拟机制,语言级别实现面向对象功能。
class Abstract{ // 抽象类, 只是定义功能, 但是不实现
public:virtual void hello() = 0;
};class B : public Abstract{public:virtual void hello(){// 具体实现}
};
f. 优先使用组合而不是继承原则(CARP,Composite/Aggregate Reuse Principle)
- 尽量使用合成/聚合, 尽量不要使用类继承
- 如果使用继承,会导致父类的任何变换都可能影响到子类的行为。
- 如果使用对象组合,就降低了这种依赖关系。
- 聚合表示一种弱的拥有关系, 体现的是A对象可以包含B对象, 但是B对象不是A对象的一部分;
- 合成则是一种强拥有, 体现严格的部分和整体的关系, 部分和整体的生命周期是一样的
我们来思考这样一样问题:
当前是80年代, 各个手机厂商和手机软件系统还没有统一, 不同的手机品牌有不同的手机软件框架, 框架下有很多的软件, 这时候想要写一个类来统一这些问题, 应该怎么写?
#include <iostream>
#include <vector>
using namespace std;
class AbstractCar{public:virtual void run() = 0;
};class Dazhong: public AbstractCar{private:public:virtual void run(){cout<<"大众出发, 迷茫的"<<endl;}
};class Benchi: public AbstractCar{private:public:virtual void run(){cout<<"奔驰, 迷茫的"<<endl;}
};class Person{private:AbstractCar* car;
public:~Person(){if(this->car != NULL){delete this->car;}}void setCar(AbstractCar* car){if(this->car != NULL){delete this->car;cout<<"这辆车已经归还.."<<endl;} // 防止上一辆车还没有归还, 就开另一辆了this->car = car;}void Doufeng(){this->car->run();}
};// 继承和组合, 优先使用组合
int main(int argc, char const *argv[])
{Person * p1 = new Person(); // 创建一个人p1->setCar(new Benchi()); // 这个人借了一辆车p1->Doufeng(); // 开着这辆车去兜风p1->setCar(new Dazhong()); // 在接一辆车, 同时上个车已经归还p1->Doufeng(); // 在去兜风delete p1; // 归还这个车删除这个人return 0;
}
g. 迪米特法则(LOD,Law of Demeter) 最少原则
一个对象应当对其他对象尽可能少的了解,从而降低各个对象之间的耦合,提高系统的可维护性。例如在一个程序中,各个模块之间相互调用时,通常会提供一个统一的接口来实现。这样其他模块不需要了解另外一个模块的内部实现细节,这样当一个模块内部的实现发生改变时,不会影响其他模块的使用。(黑盒原理)
#include <iostream>
#include <vector>
using namespace std;
// 最少知识原则
class AbstractBuilding{public:virtual string getQuality() = 0;virtual void sale() = 0;
};class BuildingA: public AbstractBuilding{public:string mQulity;BuildingA(){mQulity = "高品质";}virtual void sale(){cout<<"楼盘A 售卖 "<<mQulity<<endl;}virtual string getQuality(){return mQulity;}
};class BuildingB: public AbstractBuilding{public:string mQulity;BuildingB(){mQulity = "低品质";}virtual void sale(){cout<<"楼盘B 售卖 "<<mQulity<<endl;}virtual string getQuality(){return mQulity;}
};// 中介类
class Mediator{public:Mediator(){AbstractBuilding* bu = new BuildingA;buildings.push_back(bu);bu = new BuildingB;buildings.push_back(bu);bu = new BuildingB;buildings.push_back(bu);}~Mediator(){for(vector<AbstractBuilding*>::iterator it = buildings.begin(); it!=buildings.end(); it++){if(*it!=NULL){delete *it;}}}vector<AbstractBuilding*> buildings;// 对外提供接口AbstractBuilding* findMyBu(string quality){for(vector<AbstractBuilding*>::iterator it = buildings.begin(); it!=buildings.end(); it++){if((*it)->getQuality() == quality){return *it;}else{return NULL;}}}
};int main(int argc, char const *argv[])
{// BuildingA* build = new BuildingA();// if(build->mQulity == "高品质")// build->sale();// delete build;Mediator * Medi = new Mediator();AbstractBuilding* building = Medi->findMyBu("高品质");if(building == NULL){cout<<"没有高品质的房子了"<<endl;}else{building->sale();}return 0;
}
C++设计模式基础和模式设计基本原则相关推荐
- 「教程」游戏开发基础——游戏UI设计基本原则
UI是什么? "一般来说,UI设计的目标是产生用户界面,使用户界面能够使人类以简单愉快高效的的方式操作机器.这通常意味着操作者需要提供最少的输入来实现期望的输出,并且该机器使错误的输出最小化 ...
- 设计模式基础篇:设计原则
设计模式基础篇之设计原则 概述 开闭原则 定义 作用 实现方法 里氏替换原则 定义 作用 实现方法 依赖倒置原则 定义 作用 实现方法 单一职责原则 定义 作用 实现方法 接口隔离原则 定义 作用 实 ...
- 设计模式--1(设计模式基础,设计模式基本原则,设计模式分类)
设计模式基础 模式 在一定环境中解决某一问题的方案,包括三个基本元素–问题,解决方案和环境. 大白话:在一定环境下,用固定套路解决问题. 设计模式 是一套被反复使用.多数人知晓的.经过分类编目的.代码 ...
- 七大设计原则与设计模式(创建型模式、结构型模式、行为型模式)
七大设计原则 开闭原则.依赖倒置原则.单一职责原则.接口隔离原则.迪米特法则(最少知道原则).里氏替换原则.合成 (组合).聚合复用原则 开闭原则 定义: 一个软件实体如类.模块和函数应该对扩展开放, ...
- 反模式设计_设计模式:模式或反模式,这就是问题
反模式设计 我最近遇到了Wiki页面" Anti-pattern" ,其中包含详尽的反模式列表. 其中一些对我来说很明显. 他们中的一些让我想了一下,其他的让我想了更多. 然后,我 ...
- 学设计需要会哪些基础知识?设计的基本原则是什么?
本文由:"学设计上兔课网"原创,图片素材来自网络,仅供学习分享 学设计需要会哪些基础知识?设计的基本原则是什么?从美术到现代网页设计,设计的基础是每种视觉媒介的基础.它们甚至出现在 ...
- 翻转课堂说教案计算机,翻转课堂模式下《计算机应用基础》教学设计.doc
翻转课堂模式下<计算机应用基础>教学设计 翻转课堂模式下<计算机应用基础>教学设计 摘要:本文就以<计算机应用基础>课程的翻转课堂教学模式,探讨"翻转课堂 ...
- Java 设计模式总结及六大设计原则
设计模式总结 总体来说设计模式分为三大类: 创建型模式,共五种:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式. 结构型模式,共七种:适配器模式.装饰器模式.代理模式.外观模式.桥接模式. ...
- java设计模式总结之六大设计原则(有图有例子)
转载:https://www.cnblogs.com/jpfss/p/9765239.html 下面来总结下自己所学习的设计模式,首先我们看下各个模式之间的关系图,下面这张图是网上比较典型的一个类图关 ...
- 引用防删——JAVA设计模式总结之六大设计原则
JAVA设计模式总结之六大设计原则 从今年的七月份开始学习设计模式到9月底,设计模式全部学完了,在学习期间,总共过了两篇:第一篇看完设计模式后,感觉只是脑子里面有印象但无法言语.于是决定在看一篇,到9 ...
最新文章
- [冲昏头脑]IDEA中的maven项目中学习log4j的日志操作
- 配置aconda_centos 安装aconda
- 如何延长作用域链_通过实例理解javaScript中的this到底是什么和它的词法作用域...
- vba 循环读取单元格_利用VBA打开顺序文件,并读取
- html跨浏览器兼容性问题
- 壁式框架内力计算_钢结构墙梁内力计算
- 【2020年CSDN技术人内推活动开始啦】多家名企员工在线内推,快人一步拿Offer
- 小布老师Oracle 9i DBA Fundamentals I视频讲座
- Mybatis插件之自动生成不使用默认的驼峰式
- php分解质因数,JavaScript趣题:分解质因数
- URL.createObjectURL()方法
- Flixel横板游戏制作教程(十一)—JetPack(飞行背包)
- ckplayer播放线上视频问题
- 【php图片上传在网页显示】
- 电子邮件协议---SMTP,POP3,IMAP,MIME
- 1055 集体照 (25 分)(详解)
- 【C语言】数组(一维数组、二维数组)
- Matlab 在线版 —— 科研人员的福音!无需下载安装,可计算可作图
- 习题3:计算一周有多少分钟,多少秒?
- 国赛latex方法快速检索(入门级)
热门文章
- VS2013+VAX使用技巧
- zoom怎么解除静音_Zoom参会者入会后的注意事项
- 南昌大学大一C语言程序试卷,南昌大学C语言题库
- 博科交java插件_博科光纤交换机配置
- MQL5 编程基础:列表
- 基于C语言开发的教师管理系统
- 网络调试助手连接mysql_网络调试助手模拟MQTT协议连接百度物联网并操作时序数据库...
- maya2014中uvlayout2.08安装
- AEC产业未来发展的三大趋势,数字化只是其中之一
- 十分钟快速自制CMSIS_DAP仿真器~将ST-LINK-V2变身DAP仿真器~