软件设计入门之路

最高原则

高内聚 低耦合

正交设计四原则

  • 消除重复
  • 分离关注点
  • 减小不必要的依赖
  • 向着稳定的方向依赖

简单设计原则

简单设计

  • 通过所有测试
  • 尽可能消除重复
  • 尽可能清晰表达
  • 更少代码元素
  • 以上四个原则的重要性依次递减

SOLID 原则

正交设计,OO与SOLID

SRP 单一职责原则

每个类都应该只有一个引起它变化的原因

OCP 开放封闭原则

对扩展开放(只需要增加新的类),对修改封闭(原则上不应修改原有的任何代码),当然指的是被第一颗子弹击中的时候进行这样的设计,被第一颗子弹击中指的是变化的方向第一次明确,如果是一个崭新的需求,则和本原则无关,所以本原则关注的是 1到2 的过程,而不是 0到1 的过程

LSP 里氏替换原则

一个子类的实例应该能够替换其任何父类的实例时,它们之间才具有 is-A 关系

ISP 接口隔离原则

  • 不能强迫用户去依赖那些它们不需要依赖的接口,简单来说,就是使用多个专门的接口比使用单一的总接口要更好
  • 每个接口都是 对变化的阻抗力 被很多客户代码依赖之后就很难摆脱这个接口了,哪怕接口不合理,某种程度上是对改善的阻抗,所以定义接口的时候要慎之又慎

DIP 依赖倒置原则

  • 上层不应该依赖于下层,下层也不应该依赖于上层,双方共同依赖于抽象层
  • 一般的代码是下层提供了什么样的接口,上层代码就只能使用下层提供的这些接口,但是依赖倒置可以使得上层来定义需要被使用的接口,下层来实现对应的接口,这样使得主动权掌握在上层手中
  • 同时,下层也不应该依赖于上层,而是应该依赖于上层定义的抽象的接口,这样只要接口没有发生变化,即时双方各自的实现发生变化,并不会影响到需求的实现

多态

一个面孔多个形态,适时选择,在哪个地方做选择则会导出不同形式的多态

从数据的流动看高内聚低耦合

一个类要在其一个成员函数里面完成一个算法,其数据来源只可能有以下三个:类自身持有的数据,函数的参数,全局变量。而一个高内聚低耦合的设计应该使得每个模块(最小单位是类)之间的交互尽可能少,算法所需的数据大都是自身持有,只有少部分数据由参数传入或者是全局变量。
既然高内聚低耦合的设计中数据流通是尽可能少的,那么只要我们不断根据模块之间的数据流动来调整模块的自身结构,就可以使得类的设计能够做到高内聚低耦合,在这个调整的过程中,根据数据的交互关系,也就知道了哪些数据应该被定义成成员变量,哪些数据应该被定义成全局变量,哪些参数应该被当成函数参数。在考虑类之间关系的时候也需要考虑各个变量的生命周期。

软件设计的经典书籍

  • 人月神话
  • SICP 函数式编程
  • TDD Test Driven Design
  • C++ 实现模式
  • Jolt 图书奖 软件行业每年都会评选的优秀书籍

C++ 特点

  • 多态 一个面孔多个实现,适时选择
  • 封装 把数据隐藏起来
  • 继承 鼓励接口继承
  • 委托

class 职责

  • 价值 类的存在是为了完成什么样的任务
  • 行为 行为是一个类的灵魂,没有行为的类就是一个简单的数据结构包
  • 边界 类与外界的接口

好的架构

DCI 架构

六边形架构

clean architecture

C++ 缺陷

  • 全局变量,静态全局变量的初始化顺序问题
  • 复杂的依赖关系,include ?

C++ 语法

  • 基类的静态成员和派生类的静态成员是共享空间的,如果是一个基类多个派生类,则不同的派生类之间是共享基类的静态成员的
  • 能用 const& 尽可能使用 const&,包括函数参数以及返回值,需要考虑的是变量的生命周期
  • 前置声明,对象的引用和指针可以看成是同样一个东西,都可以使用前置声明,如果是对象的话则因为要知道分配的空间大小,所以不能使用前置声明,如果使用到其中内部的方法,也不能使用前置声明

visitor 设计模式与 lambda 函数

visitor 能传的参数其实是函数指针,
一种是定义的自由函数
一种是函数类(类重载了() 运算符,能够处理参数)
在引入lambda表达式之后,能够很方便地完成以前需要使用函数类才能完成的功能,而且 lambda 表达式的引入也解决了定义函数类的复杂性

空对象模式

策略模式

往往策略是纯算法类,则可以作为常量存在,如果内部需要数据的话,则是需要创建实例
策略不应该变成使用策略的类的成员变量
策略是闭包的 策略里面包含策略还是策略

测试的一些手段

fake 用内存数据库替换实际数据库
stub 将用到的函数给一个简单的使用,链接不使用原本的函数,使用stub的函数
mock 一个测试框架

duck typing 模板类

关于枚举

定义的一个枚举类型和枚举变量之间的关系,也是一个 is-A的关系
有时候会使用枚举来建立一个映射关系,可以想想这个枚举类型是不是一定是必须的,能不能直接用枚举变量对应的映射量作为判断的依据

组合式设计

不同类组合在一起,完成一些功能
组合式设计 Format(Length(1,Mile), BASE)

其他

  • 测试是手段,设计是目的
  • 阅读源代码的顺序是 测试用例 头文件 源代码
  • 要想学会好的设计,需要从设计理念和设计技法两个角度去思考问题

猜你喜欢

转载自www.cnblogs.com/race-with-unknown/p/10807110.html