代码大全学习笔记4

第六章

6.3 有关设计和实现的问题

——类内部的设计和实现

包含(“有一个。。。”的关系)

  1. 通过包含来实现“有一个”的关系
  2. 在万不得已时通过private继承来实现“有一个”的关系:这部分没有太看懂;
  3. 警惕有超过约7个成员变量的类:研究表明人在做其他事情时能记住离散项目的个数是7±2;

继承(“是一个。。。”关系)

——集成的目的在于,通过“定义能为两个或更多个派生类提供共有元素的基类”的方式写出更精简的代码。

  1. 用public集成来实现“是一个。。。”的关系:积累对派生类将会做什么设定了预期,也对派生类能怎么运作提出了限制;

  2. 要么使用继承并进行详细说明,要么就不要用它:继承给程序增加了复杂度,因此它是一种危险的技术,如果某个类并未设计为可被继承,就应该把它的成员定义为non-virtual(c++)、final(java)或者non-overridabel(microsoft visual basic),这样你就无法继承它了;

  3. 遵循Liskov替换原则:派生类必须能通过基类的接口而被使用,且使用者无须了解两者之间的差异;也就是说,对于基类中定义的所有子程序,用在它的任何一个派生类中时的含义都应该是相同的;

  4. 确保值继承需要继承的部分
    继承而来的子程序有三种情况:
    ① 抽象且可覆盖的子程序是指派生类只继承了该子程序的接口,但不继承其实现;
    ② 可覆盖的子程序是指派生类继承了该子程序的接口及其默认实现,并且可以覆盖改默认实现;
    ③ 不可覆盖的子程序是指派生类继承了该子程序的接口及其默认实现,但不能覆盖该默认实现;

  5. 不要“覆盖”一个不可覆盖的成员函数:派生类中的成员函数不要与基类中不可覆盖的成员函数重名;

  6. 把共用的接口、数据及操作放到继承树中尽可能高的位置:如果你发现把一个子程序移到更高的层次后会破坏改成对象的抽象性,就该停手了;

  7. 只有一个实例的类是值得怀疑的

  8. 只有一个派生类的基类也值得怀疑:为未来要做的工作着手进行准备的最好方法,就是让眼瞎的工作成果尽可能的清晰、简单、直截了当;

  9. 派生后覆盖了某个子程序,但在其中没做任何操作,这种情况也值得怀疑:这就说明你的派生类和基类的属性和实现方式不一样;在这里插入图片描述在这里插入图片描述

  10. 避免让继承体系过深:过深的继承层次会显著导致错误率的增长;

  11. 尽量使用多态,避免大量的类型检查:频繁重复出现的case语句有时是在暗示,采用继承可能是中更好的设计选择——尽管并不总是如此;

  12. 让所有数据都是private(而非protected):如果派生类帧的需要访问基类的属性,就应提供protected访问器函数;

多重继承

——下面来总结一下何时可以使用继承,何时又该使用包含:

  1. 如果多个类共享数据而非行为,应该创建这些类可以包含的共用对象。
  2. 如果多个类共享行为而非数据,应该让它们从共同的基类继承而来,并在基类里定义共用的子程序。
  3. 如果多个类既共享数据也共享行为,应该让它们从一个共同的基类继承而来,并在基类里定义共用的数据和子程序。
  4. 当你想由基类控制接口时,使用继承,当你想自己控制接口时,使用包含。

成员函数和数据成员

  1. 让类中子程序的数量尽可能少:类里面的子程序的数量越多,则出错率也就越高;
  2. 禁止隐式地产生你不需要的成员函数和运算符:(没有太读懂这部分);
  3. 减少类所调用的不同子程序的数量:类里面的错误数量与类所调用的子程序的总数是统计相关的,类所调用的其他类的数量越高,其出错率也往往会越高;
  4. 对其他类的子程序的简洁调用要尽可能少

构造函数

  1. 如果可能,应在所有的构造函数中初始化所有的数据成员
  2. 用私用(private)构造函数来强制实现单件属性(没搞明白)
  3. 优先采用深层复本,除非论证可行,才采用浅层复本

猜你喜欢

转载自blog.csdn.net/u012850592/article/details/89438598