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

实际上也就是要满足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. linux shell学习五

    参考:https://www.linuxdaxue.com/ Shell函数 因为函数是脚本类语言,在执行时是逐行执行的,因此,Shell 函数必须先定义后使用. Shell 函数的定义格式如下: [ ...

  2. OpenCV---色彩空间(二)HSV追踪颜色对象和通道分离与合并

    一:HSV追踪有颜色对象 def inRange(src, lowerb, upperb, dst=None) #lowerb是上面每个颜色分段的最小值,upperb是上面每个颜色分段的最大值,都是列 ...

  3. UVA 10479 The Hendrie Sequence

    https://vjudge.net/problem/UVA-10479 打表找规律: 1.根据n可以确定第n项在上表中第i行 2.减去前i-1行,就得到了n在第i行的第j个 3.第i行的规律:1个i ...

  4. 2015/10/9 Python基础(21):可调用和可执行对象

    在Python中有多种运行外部程序的方法,比如,运行操作系统命令或另外的Python脚本,或执行一个磁盘上的文件,或通过网络来运行文件.这完全取决于想要干什么.特定的环境包括: 在当前脚本继续运行 创 ...

  5. 使用CSS3+JQuery打造自定义视频播放器

    简介 HTML5的<video>标签已经被目前大多数主流浏览器所支持,包括还未正式发布的IE9也声明将支持<video>标签,利用浏览器原生特性嵌入视频有很多好处,所以很多开发 ...

  6. uefi模式下win10安装双系统ubuntu18.04LTS

    自己折腾了半天,血与泪啊(难得一个可爱的周末 wwww我一定要写下来 跟这个博客几乎一模一样了 https://blog.csdn.net/xrinosvip/article/details/8042 ...

  7. Sublime之插件的安装(三)

    今天在写js的时候,突然想到一个问题就是能不能快速的对齐的插件,当当当~~~sublime这么神器当然有,那就是:Alignment插件 如果你写的代码是这样的: var a = , b =, ccc ...

  8. spring3-spring的事务管理机制

    1. Spring的事务管理机制 Spring事务管理高层抽象主要包括3个接口,Spring的事务主要是由他们共同完成的: PlatformTransactionManager:事务管理器—主要用于平 ...

  9. 对Feign的请求url 重写

    需求:对当前请求的 url 重新构建 debug feign 的执行可知,重写 LoadBalancerFeignClient 类中的 execute 方法即可控制当前请求的url 代码分析 当引入  ...

  10. java类中访问属性

    package first; public class for_protect { private int age=10; int number = 100; public void show(){ ...