如何增强代码设计能力
c++语言
- 根本目的:实现近乎零开销的抽象。
- 通过语言将抽象的构造直接映射到硬件设备
- 不用的东西不付出代价,用到的东西手工代码不会更好
- 使用c++进行研发的道
- 机器思维:将抽象构造更好的映射到设备
- 抽象思维:对复杂的管理
- 结论:将技术和关键词分别使用机器思维和抽象思维进行理解
- c++研发能力的术
- 类型系统(1~2年掌握):语言的语法细节,是c++的基础
- 编译映射:编译器在不同场景下对代码处理方式的差异
- 内存管理(3~5年掌握)
- 设计范式
- 习语规范(6~9年掌握):用于编程语言本身的交流
- 设计范式的组成
- 面向过程
- 面向对象
- 泛型编程
- 函数式编程
- 模版元编程
- 编程分析方法
时空人
- 时间分析:编译时和运行时发生的绑定关系
- 空间分析:数据应该存放的数据结构
- 人物分析:与框架的耦合关系
- 标准库中的string存储位置:非new的编译映射方式为比较小的放在栈上,比较大的放在堆上,默认区分为14字节
- 建立宽阔的思维:与其他语言在内存模型和设计范式上的异同
- 设计的艺术之处在于不同情况下找到最优解,并能长期适应对未来的变化。
设计原则
- 简单设计四原则(重要性依次降低)
- 实现功能:能够通过所有测试,是软件设计的基本要求
- 易于重用:具有更加适应变化的能力,高内聚,低耦合。
- 易于理解:团队开发的基本要求
- 没有冗余:最简单的、恰如其分的(只实现当前功能)、不做任何过度设计的系统
- 正交设计原则
- 消除重复:重复意味着低耦合,会提高软件的维护成本
- 分离职责:一个模块有多个职责意味着多个变化方向,应该分离变化方向形成单一职责。
- 缩小依赖范围:API应该高内聚,避免强迫客户依赖他不需要的东西
- 依赖于稳定:依赖更加稳定的耦合点可以避免受到依赖的影响
- 整洁代码三原则
- KISS原则
Keep It Simple and Stupid,平衡好简单和易于理解。不要使用奇技淫巧进行过度优化,不要过度设计,瞧不上简单的东西 - YAGNI原则
当前不需要就不做。 - DAY原则
减少重复的代码
- KISS原则
- SOLID五大设计原则
- 单一职责原则SRP
一个类的职责过多,如果其中一个职责变化可能破坏整个类的稳定性。每个类单一职责可以解耦并增强内聚性 - 开放封闭原则OCP
对拓展开放,对修改封闭。即当软件需要变化时,尽量通过扩展软件实体的行为来实现变化,而不是通过修改已有的代码来实现变化。 - 里氏替换原则LSP
子类可以替换父类并出现在父类能够出现的地方。这就要求所有子类严格共享非抽象方法,而只能对抽象方法进行重定义。 - 接口隔离原则ISP
一个接口应该尽量细化为多个专用接口,减少对于接口中不需要的方法的依赖 - 依赖倒置原则DIP
多变的具体应依赖稳定的抽象,高层模块不应该依赖底层模块,二者都应该依赖抽象。
- 单一职责原则SRP
- 面向对象三原则
- 封装责任,隔离变化
使用封装来创建对象之间的分解层,让设计者可以在分解层的一侧进行修改,而不会对另一侧产生不良的影响,从而实现层次间的松耦合 - 优先使用对象的组合,而不是类继承
继承在一定程度上破坏了类的封装性,而组合实现高内聚的同时提高了灵活性。 - 针对接口编程,而不是针对实现编程
- 封装责任,隔离变化
设计习语
- RAII资源获取即初始化(Resource acquisition is initialization)
- 将资源的使用和维护封装在类中,在构造函数中获取资源并初始化资源管理相关的数据结构,在析构函数中释放资源,将系统资源的生命周期和对象的生命周期进行绑定,以防止内存泄漏。
- Scope Guard范围守卫
- 设定资源使用的作用范围,一旦超出范围,ScopeGuard会自动释放资源
- NVI非虚接口
- 基类中接口函数尽量设置为非虚拟的,这样基类对于接口具有完全的控制权,让基类在变化前更加稳定,eg:统计接口调用数量,只需要在基类的接口函数中添加计数功能即可,如果生命为虚函数则需要在派生类中统计,会极大的增加复杂性
- Pimpl指向实现的指针(Pointer to implementation)
- 原理:将头文件中类定义的实现细节使用非完全类型指针代替,具体实现都隐藏在cpp文件中。
- 作用:减少了实现类对于头文件的依赖性,防止了类成员变更导致的头文件重编译,即使用头文件的指针提高了实现的灵活性
- EBCO空基类优化
- 空基类被继承后没有任何数据成员,相应对象均为1个字节
- 为什么C++中不允许类的大小是0:空类对象至少为1个字节(字节对齐可能导致为4个字节),因为两个对象间字节数使用地址除以类型大小可能导致除零异常。
- CRTP奇异递归模板模式
- 通过模板实现静态绑定,省去动态绑定中查询虚函数表带来的开销。
- PolicyDesign策略设计
- Mixin混入类
- SOO小对象优化
- LocalBuffer本地缓存
- Copy-On-Write写时拷贝
- Type Erasure类型擦除
- Named Template Arguments命名模板参数
- Method Chain方法链