C++七项设计原则和常见设计模式
一、C++面向对象设计的的七大设计原则
- 单一职责原则: 就是一个类只负责一个职责, 只有一个引起变化的原因。
例如:调制解调器:将连接看作一个职责,数据传送看作一个职责,两者需要分离开; - 里氏替换原则:任何基类可以出现的地方,子类一定可 以出现,子类一定要能够被当成基类使用;
例如:手枪,步枪,机关枪,玩具枪等都属于枪,但如果在射击游戏场景中,就不能够使用玩具枪,因此,玩具枪应该单独成为一个类,否则就违反了里氏替换原则; - 依赖倒置原则:依赖倒置原则就是要依赖于抽象,不要依赖于具体。简单的说就是对抽象进行编
程,不要对实现进行编程,这样就降低了客户与实现模块间的耦合;
例如:要设计一个自动驾驶系统,该系统应该这一来汽车这一抽象类型,而不应该依赖于具体的某一型号的车; - 迪米特法则:又叫最少知识原则(Least Knowledge Principle LKP), 就是说一个对象应当对其他对象有尽可能少的了解。–降低类之间的耦合性,但过度使用该法则,可能会导致很多的中介类出现;–尽量降低各个成员的权限;
- 开放封闭原则:软件实体应该对扩展开放(意味着有新的需求或变化时,可以对现有代码进行扩展,以适应新的情况),而对修改封闭(意味着类一旦设计完成,就可以独立其工作,而不要对类进行任何修改)。
—核心思想:对抽象编程,因为抽象相对变化少,而通过继承的方式进行扩展;
—例如:对于一个银行系统来说,不应该将多种业务组合成一个类,而是每种业务都写成一个类 ,这样,扩展新的业务时,只需要增加新的继承类即可; - 接口隔离原则:不应该强迫客户依赖于他们不用的方法;尽量使用多个功能单一的接口,而不是用一个总的接口;
- 合成复用原则:尽量使用合成/聚合, 而不是使用继承,is 关系是继承,而has关系是成员;例如:银行卡,储蓄卡,信用卡三者的关系;储蓄卡只能够存取款;信用卡能够透支;银行卡同时拥有两者的功能;是has的关系;
二、常见设计模式
1. 单例模式:
-
用途:单例模式主要解决一个全局使用的类频繁的创建和销毁的问题。单例模式下可以确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。
-
实现方法:
- 构造函数使用private进行修饰;外部函数无法通过构造函数的方式对其进行构造;
- 提供一个静态成员对象,是该类自身的唯一一个实例,可以通过域的方式对其进行访问;
- 饱汉式构造方法:直接在类装载时就实例化,即直接在类定义时对该静态成员对象进行初始化;—可能会产生垃圾对象;
- 饿汉式构造方法:在第一次(获取实例函数)被调用的时候进行初始化;之后再调用的时候检查是否被调用过;–使用锁机制,防止多次访问,可以这样,第一次判断为空不加锁,若为空,再进行加锁判断是否为空,若为空则生成对象。
- 优缺点分析:
- 优点:在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例(比如管理学院首页页面缓存);避免对资源的多重占用(比如写文件操作)。
- 缺点:没有接口,不能继承;与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么样来实例化。
template <typename T>
class Singleton
{
public:
static T& get_instance() {
static T t;
return t;
}
private:
Singleton(){}
~Singleton(){}
Singleton(Singleton&) {}
Singleton(const Singleton&) {}
Singleton& operator= (Singleton&) {}
Singleton& operator= (const Singleton&) {}
};
2. 工厂模式:
- 工厂模式,定义一个创建对象的接口(便于维护),将对象的创建过程延迟到子类(便于扩展),由子类决定实例化哪一个产品;
- 主要组成:工厂抽象类;工厂类;产品抽象类;产品类;—每个产品对应一个工厂;
- 分类:
- 简单工厂模式:可以根据参数的不同返回不同类的实例。
- 工厂方法模式:对象的实例化延迟到子类,子类决定实例化哪一个对象;
- 抽象工厂模式:支持多种产品的创建;
- 工厂模式有什么好处?
- 便于维护:将对象的创建过程集成到接口中,用户只需要调用接口,不用管具体的创建逻辑;—否则,创建过程四散在各文件代码中;
- 便于扩展:由于使用了开放封闭原则,将对象的创建推迟到子类,当需要创建新的对象类型时,便于进行扩展;
- 没有工厂,用户需要自己去创建一辆车;代码中四散着创建逻辑;有工厂,用户只需要给钱,管工厂要一辆车就行;简单工厂违背了开放封闭原则;因此,使用子类延迟创建的方法支持扩展;
3. 观察者模式:
-
观察者模式:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动更新;一般有四个类,抽象观察主体;具体观察主体;抽象观察者;具体观察者;
-
两种模式类型
- 推模式: 观察主体的状态发生改变时,主动将相关的信息推给观察者;
- 拉模式:观察者直接维持一个观察主体的引用,当观察主体的模式改变时,根据引用的信息更新自己;这种模式便于观察者类型的多样性扩展;
4. 装饰器模式:
-
装饰器模式:提供一个装饰类,使用对象成员的方式来代替继承,即使用对象的关联关系来代替继承关系,能够用来动态扩展一个实现类的功能,避免类型体系的快速膨胀;
-
优缺点:
- 优点:装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式;
- 缺点:多层装饰比较复杂。
注:以上为本人学习过程中所做笔记整理,如有错误,敬请指正。