【C++代码整洁之道】第六章 面向对象

《C++代码整洁之道》学习笔记,系列之六:面向对象

1. 面向对象思想

  • Simula-67被认为是第一个面向对象OO的编程语言

  • 面向对象是一种思维方式,而不是所使用的编程语言本身的问题

2. 抽象

  • 解决复杂问题的关键因素

3. 类的设计原则

  • (1)让类尽可能小

    • ① 同样的,让函数尽可能小
    • ② 理论上,一个类不要超过50行(Line of Code, 即LOC不超过50)
  • (2)单一职责原则 SRP = Single Responsibility Principle

    • ① 单一职责原则是一个比LOC更好的标准。如果这些类没有违反SRP,那就完全没问题
  • (3)开闭原则 OCP

    • ① 软件实体如模块、类、函数等,对拓展extension应该是开放的,但是对修改应该是封闭
    • ② 因为已有代码已经经过充分测试,如果任何新的需求都导致已有代码的修改,那将是致命的
    • ③ 在面向对象中,继承是一种支持该原则的方法
  • (4)李氏替换原则LSP

    • ① final关键字,一方面能避免函数在派生类中被重写,会报错;另一方面可以将类标记为final,不能将该类作为继承的基类
    • ② 李氏替换原则意味着:派生类必须完全可以替代其基类,如通过继承长方形类来实现正方形类,对长宽关系进行了限制,这就违反了李氏替换原则
    • ③ 李氏替换原则有以下规则:
        1. 基类不能在派生类中削弱
        1. 基类的不变量不能在派生类中更改
        1. 派生类中不应该在新引入的成员函数中改变不可变的成员
    • ④ RTTI = Run-Time Type Information,运行时类型信息,是一种设计坏味道design smell,是不好的面向对象的软件设计
    • ⑤ 在编程中,正方形不是矩形的子类型,违反了LSP。根据KISS原则,实现正方形最好的方法是,在矩形类中添加一个是否是正方形的查询方法即可;
    • ⑥ 如果一定要实现正方形类,也不能继承矩形类,而应该从Shape虚基类继承;为了不违反DRY原则,使用矩形类的实例作为正方形类的内部实现,Rectangle impl,这种被称为"优先组合而非继承"
  • (5)接口隔离原则ISP = Interface Segregation Principle

    • ① ISP接口隔离原则指出,接口不应该包含那些与实现类无关的成员函数。比如抽象鸟类实现Penguin类无法提供Bird::fly()的有效实现,却需要覆盖该成员函数
    • ② ISP指出,我们应该将"宽接口"分离成更小且高度内聚的接口(角色接口),然后可以非常灵活地组合这些小的角色接口
  • (6)无环依赖原则

    • ① 环依赖:两个类直接或间接地相互依赖,比如customer和account两个类
    • ② 当形成环依赖时,问题显而易见,将会导致c++编译器错误
    • ③ 将引用或指针与前置声明结合使用可以避免编译错误,但还是没有解决设计问题,那就是环依赖,这样的代码可能导致悬浮指针或其他未定义的行为,也没法进行独立测试
    • ④ 类级别的环依赖导致对组件级别的环依赖
    • ⑤ 无环依赖原则指出:组件或类的依赖图应该没有环。环依赖是紧耦合的一种不良表现形式,应不惜一切代价避免
  • (7)依赖倒置原则DIP

    • ① DIP = Dependency Inversion Principle,依赖倒置原则
    • ② DIP包含两个原则
        1. 高级模块不应依赖于低级模块,两者依赖于抽象
        1. 抽象不应依赖于细节,细节依赖于抽象
  • (8)不要和陌生人说话(迪米特法则)

    • ① Law of Demeter,也称为最少知识原则。假定以下规则
        1. 允许成员函数调用类内其他成员函数
        1. 允许成员函数调用类内成员变量的成员函数
        1. 成员函数可以直接调用其参数的成员函数
        1. 成员函数可以调用局部对象的成员函数
    • ② 迪米特法则,比如司机开车,司机不应直接去操作引擎内的燃油泵、点火系统和马达,司机对零部件的依赖应该取消。否则,如果内燃机被电力系统取代,那么必须调整司机类的视线,这违反了开闭原则,将引擎内部暴露在环境中违反了信息隐藏原则
    • ③ 所以迪米特法则可以显著减少依赖性,降低耦合程度,并遵循信息隐藏原则和开闭原则
  • (9)避免"贫血类"

    • ① 没有任何功能,全是数据存取setter/getter,严重违反了信息隐藏原则。这种类称为贫血类
  • (10)只说不问

    • ① Tell, Don’t Ask
    • ② 零件自己决定如何执行一个命令,而不是在上层处理零件的各种状态,这样分支数量众多,圈复杂度也高
  • (11)避免类的静态成员

    • ① 静态成员函数偏向于面向过程的编程风格,在静态变量的协助下,破坏了封装,对象不再完全控制其状态
    • ② 建议避免使用静态成员变量和静态成员函数

 


 

【参考文章】
[1]. C++代码整洁之道

created by shuaixio, 2024.11.17

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值