一,继承只应被用来为特化层次结构建模

实际上也就是要满足LSP原则,水果类<-榴莲的继承是特化

 
二,派生类必须知道他们的基类,基类不应当知道他们的派生类  
复用的前提
 
三,基类中的所有数据都应该是私有的,不要使用保护数据(方法不在此原则约束下)   
数据封装,物体的重量看起来可以用一个保护数据来表达,而不是get/set方法,但是考虑其他星球上,那么重量的应该实现为质量*加速度的时候呢?
 
四,理论上,继承层次越深越好   
继承越深,意味着复用的功能越多
 
五,如果没有合适的可视化工具显示类继承层次,那么在实践中,继承层次最合适的深度是7+-2(7是一个神奇的数字,是一个普通人能保持短期记忆的数字)
 
六,所有的抽象类都应该是基类   
没有派生类的抽象类毫无意义,连创建都创建不了
 
七,与六对应,所有的基类都应该是抽象类   
违反这条原则的后果是将来可能会有大量的改名操作(在进一步抽象的过程中类名不在合适,在适应变化的时候会出现)
 
八,把数据,行为和/或接口的共性尽可能地放到继承层次的高端    
公共数据经常意味着公共行为
 
九,如果两个或多个类共享公共数据(但没有公共行为),那应该把公共数据放在一个类中,给个共享这些数据的类都包含这个类(而不是继承)    继承所抽象的是行为,而不是数据,和八对应.   
对静态不变的类型/数据进行判断的代码基本上可以说是设计不到位的表现,如针对水果而言    if(type is apple)...    else if(type is orrange) ...    ...    但是对可变的数据进行判断在一定程度上可以接受,但是如果逻辑复杂,则需要考虑状态机/策略来封装.
 
十,如果两个或多个类有共同的数据和行为(就是方法),那么这些类的每一个都应当从一个表示了这些数据和方法的公共基类继承
 
十一,如果两个类或更多类共享公共接口,那么只有他们需要被多态使用时,才需要公共基础类.   
如果不需要多态使用,干什么要继承而不是组合,组合优于继承
 
十二,对对象类型的显式的分情况分析一般都是错误的设计.在大多数这种情况下,设计者应当使用多态   
如:   
如果你是类型A,则做这件事   
如果你是类型B,则做那件事   
如果你是类型C,则做其他的一件事
 
十三,对属性值的显式分情况分析常常是错误的.类应该解耦合成一个继承层次结构,每个属性值都被变换成一个派生类    
红绿黄球的例子    
如果颜色不影响到球的行为,则不需要抽象一个球的基础类,然后派生3个颜色球类     反之,则需要
 
十四,不要通过继承关系来为类的动态语义建立模.试图用静态语义关系来为动态语义建模会导致在运行时切换类型    
如门的状态属性:开和关,千万不要出现OpenedDoor和ClosedDoor类
尝试用状态机来处理.
 
十五,不要把类的对象变成派生类.对任何只有一个实例的派生类都要警惕.  
如下面的继承关系就是问题:  
汽车制造商  <=
                  福特
                  大众
                  本田
 
十六,如果你觉得需要在运行时创建新的类,那么请退一步仔细想想是不是要创建对象.把这些对象概括成一个类  
组合模式是一个很明显的例子
 
十七,在派生类中用空方法来覆盖基类中的方法应该是非法的.  
如果这样做可行的话,任何类都可以成为任何其他类的派生类,反正把基类的所有方法都用空方法屏蔽掉然后加自己的方法就是.
 
十八,不要把可选包含(可能为null的属性)同对继承的需要混淆起来.否则会带来泛滥成灾的类.  
狗<=
    会摇尾巴的狗
    不会摇尾巴的狗
    尾巴受伤的狗
    等等
 
十九,在创建继承层次时,试着创建可复用的框架,而不是可复用的类  
关注创建的是接口,而不是具体的类.与DIP原则类似
经典故事:
  按照第一想法,所有的哺乳动物都是怀胎产子,矛盾在鸭嘴兽是哺乳动物,但是是蛋生,那么我们该怎么建立模型呢?
  还有鸵鸟非鸟的问题

OOD沉思录 --- 继承的更多相关文章

  1. OOD沉思录 --- 类和对象的关系 --- 包含关系4

    4.9 在实现语义约束时,最好根据类定义来实现.但是这经常会导致泛滥成灾的类,在这种情况下约束应当在类的行为中实现,通常在类的构造函数中实现,但不是必须如此. 还是以汽车为例,我们看汽车的定义,为了集 ...

  2. OOD沉思录 --- 类和对象的关系 --- 包含关系3

    4.7 类包含的对象数目不应当超过开发者短期记忆数量,这个数目通常应该是6左右 4.8 让系统在窄而深的包含体系中垂直分布 假设有如下两份菜单: 正餐 --->甜瓜 --->牛排 ---& ...

  3. OOD沉思录 --- 类和对象的关系 --- 包含关系2

    4.6 尽量让类中定义的每个方法尽可能多地使用包含的对象(即数据成员) 这其实就是高内聚的翻版强调.如果每个类的情况并非如此,那很可能是这一个类表示了两个或更多的概念,记住一个类只应该表示一个概念. ...

  4. OOD沉思录 --- 类和对象的关系 --- 包含关系1

    4.5 如果类包含另一个类的对象,那么包含类应当向被包含的对象发送消息(调用方法).  也就是说,所有的包含关系都应当是使用关系. 如果不是这样,那么包含的类有什么用处呢?当然,面向过程的开发人员会想 ...

  5. OOD沉思录 --- 类和对象的关系 --- 使用关系原则

    4.1 尽量减少类的协作的数量,即减少使用者和被使用者的数量. 协作意味着一定程度的耦合,但是完全没有协作的类也是没有意义的,最多只能作为一个库使用. 通过抽象,依赖接口,可以最大程度减少依赖的实现类 ...

  6. OOD沉思录 --- 类和对象的关系 --- 使用关系

    使用关系 对象A的方法MethodA使用了B的方法MethodB,则表示A对B存在使用关系 使用关系的最关键问题在于,A如何找到B,存在6种方案 方案一: A包含了B,B作为一个成员定义在A的类中,那 ...

  7. OOD沉思录 --- 面向动作与面向对象 --- 避免泛滥成灾的类

    3.7 从设计中取出不需要的类 只有Get/Set方法的类不算是一个必要的类,Get/Set方法也不算是有意义的行为.这种类降级为属性更加合适. 3.8 去除系统外部的类 如果一个类只调用系统领域的方 ...

  8. OOD沉思录 --- 面向动作与面向对象 --- 避免全能类

    面向过程的软件开发通过非常集中化的控制机制来分解功能,在程序设计中表现就是大量的条件判断,深层次的循环嵌套等. 这种模式下,我们可以通过分析方法的参数,局部变量及其访问的全局变量来得到方法对数据的依赖 ...

  9. OOD沉思录 --- 导引

    一个对象一定会有如下4个属性: 1,它的身份标示,可能只是它在内存中的地址; 2,它的类的属性(通常是静态属性)和这些属性的值(通常是动态的); 3,它的类的行为(从实现者的角度看); 3,它的公开接 ...

随机推荐

  1. HTTP、TCP、 UDP、 IP 、 Socket的关系

    TCP和UDP协议是传输协议,IP是网络层协议.传输协议和网络层协议主要解决数据如何在网络中传输,或者说TCP/IP 定义了电子设备如何连入因特网,以及数据如何在它们之间传输的标准.TCP负责发现传输 ...

  2. 前端PHP入门-028-文件操作-掌握级别

    作为刚入门我们员经常会干的意见事情是ctrl+c和ctrl+v,鼠标右键删除文件.会control+c(或右键)复制.粘贴文件以及新建文件,还可以设置文件的是否为只读文件等等 可不可以写入修改配置文件 ...

  3. [DeeplearningAI笔记]序列模型2.10词嵌入除偏

    5.2自然语言处理 觉得有用的话,欢迎一起讨论相互学习~Follow Me 2.10词嵌入除偏 Debiasing word embeddings Bolukbasi T, Chang K W, Zo ...

  4. Mac环境下SVN的配置和使用

    简单记录一下在Mac环境下,SVN的配置步骤和使用相关.(Mac自带了svn的服务器和客户端功能,简单配置一下即可使用) 一.SVN的配置方法 1. 创建一个仓库目录,比如在/Users/你的用户名 ...

  5. LightOJ 1244 - Tiles 猜递推+矩阵快速幂

    http://www.lightoj.com/volume_showproblem.php?problem=1244 题意:给出六种积木,不能旋转,翻转,问填充2XN的格子有几种方法.\(N < ...

  6. How to reset XiaoMi bluetooth headphone Youth edition.

    To reset the speaker 1. Long press the phone call button to shut off the speaker 2. Connect the char ...

  7. XMLHttpRequest 整理

    看了SF 上的一篇文章感触颇深:你真的会使用XMLHttpRequest吗? 在这我写上我读后的笔记: <!DOCTYPE html> <html lang="en&quo ...

  8. NYOJ 133 子序列 (离散化)

    题目链接 描述 给定一个序列,请你求出该序列的一个连续的子序列,使原串中出现的所有元素皆在该子序列中出现过至少1次. 如2 8 8 8 1 1,所求子串就是2 8 8 8 1. 输入 第一行输入一个整 ...

  9. javac -cp java -cp

    ///////////////////////////////////////////////////////////////////////////////////// 编译java文件的命令都知道 ...

  10. 零基础讲解JavaScript函数

    一 JavaScript函数1 什么是函数  函数是一组代码(指令)的集合,通常用来完成某个单一的功能.(书的目录和章节,电视剧剧集的名称等)2 为什么要使用函数  2.1 把复杂程序划分成不同的功能 ...