OO设计基本原则
OO本身就是一种大的设计模式,它是随着软件规模越来越大产生出来帮助人们建模和开发的理念,生来就带着封装、继承、多态等可复用基因。为了充分发挥这些基因的功效,使用者需要遵守一定的原则,就是所谓的面向对象设计原则。然而正确地使用这些运用这些原则并不容易,只有把这些原则吸收成为身体一部分的经验丰富的工程师才能在遇到各种问题时,灵活地使用它们。一些OO大师为了方便新手更好地理解OO原则,就根据经验假象了一些软件设计过程中经常碰到的问题,并给出了遵循OO原则的解决这些问题的设计方案,就产生了设计模式,正如设计模式的定义:设计模式就是我们周围不断重复发生的问题,以及该问题的解决方案的核心【Christopher Alexander】。
OO设计原则是根本,设计模式是设计原则在具体问题中的应用。本文将尝试汇总究竟有哪些OO设计原则,以及它们之间的内在联系。
首先不得不提著名的SOLID原则:Single responsibility, Open closed, Liskov substitution, Interface segregation, Dependency inversion。
单一责任原则SRP(Single Responsibility Principle):一个类/对象只有一个引起变化的原因。换言之,一个类只有一个类型责任。(高内聚)
开放封闭原则OCP(Open Closed Principle):软件实体对扩展开放(对于系统),修改关闭(对于成型模块)。
里氏替换原则LSP(Liskov Substitution Principle):子类的实例能够替换其父类的实例。基本地说,也就是“子类型必须能够替换掉它们的父类型”。一个软件实体如果运用的是一个父类的话,那 么一定适用于其子类,而且它察觉不出父类对象和子类对象的区别。在程序中,把父类都替换成它的子类,程序的行为没有变化.(正方形不是长方形),最有难度的约束设计.
接口分离原则ISP(Interface Segregation Principle):使用多个专门的接口比使用单一的总接口要好。一个类对另一个的依赖性建立在最小的接口上。
依赖倒置原则DIP(Dependency Inversion Principle):依赖抽象不要依赖具体实现。(1)高层模块不应该依赖底层模块。两个都应该依赖抽象(2)抽象不应该依赖细节,细节应该依赖于抽象
其它OO设计原则:
DRY原则(Don't repeat yourself):避免重复的代码,这样会降低可维护性。
封装变化原则:把会变化的部分独立出来,让其他部分不受影响。
组合复用原则:优先使用组合而不是继承,通过获得对其他对象的引用而在运行时刻动态改变对象行为。
针对接口编程而不是实现:依赖抽象类的接口,可以在运行时改变对象行为,也就是多态。
迪米特法则LoD(Law of Demeter):也称为最少知识原则LKP(Least Knowledge Principle)。就是说,一个对象应当对其它对象有尽可能少的了解.如果两个类不必彼此直接通信,那么这两个 类就不应当发生直接的相互作用。如果其中一个类须要调用另一个类的某一个要领的话,可以通过第三者转发这个调用。“。它强调我们在封装类的时候,在类的设计结构上,每一个类都 应当降低成员的访问权限。类与类之间的耦合度越低越好,因为一个类被修改,不会对有关联的其他类也执行 修改。(发布-订阅模式),低耦合.
松耦合原则:对象之间的依赖尽量的少。
好莱坞原则:别调用我们,我们会调用你。
看到这么多设计原则可能会有些头晕,就像小时候妈妈教我们的做人大道理,宽泛而很难体会,没有经验的工程师只能把他们背下来,在以后的实践过程中慢慢体会。我们可以初步分析一下这些原则的内在联系。
其中DRY原则和松耦合原则,是所有原则的基础,不仅是OO设计的根本,也是所有软件设计的灵魂,我们暂且不归为OO设计原则,应该作为公理存在潜意识中,就像”你要做个好人“。
封装变化原则,目的是为了提高代码的可维护性,就面向对象设计而言,开放封闭原则就包含了封装变化原则,不仅包含了,跟进一步用扩展的方法来约束变化,所以该原则可以纳入开放封闭原则。
针对接口编程而不是实现与依赖倒置原则很相似,可以说是同一原则的着眼点不同,针对接口编程原则强调的是接口的客户,接口使用者不用关心接口的具体实现;依赖倒置原则强调的是高层模块与底层模块的依赖关系。其实二者是一个原则。
好莱坞原则是依赖倒置原则在框架设计中的一种技巧,可以不作为一个单独的原则。
经过萃取,我们留下了七大面向对象设计原则,他们是:单一责任原则、开放封闭原则、里氏替换原则、接口分离原则、依赖倒置原则、组合复用原则、迪米特法则。
※单一职责原则:就一个类而言,应该仅有一个引起它变化的原因。
单一是一个类的优良设计。交杂不清的职责将使得代码看起来特别别扭牵一发而动全身,
有失美感和必然导致丑陋的系统错误风险。
※开放封闭原则:是说软件实体(类、模块、函数等等)应该可以扩展但不可修改。
实现开开放封闭原则的核心思想就是对抽象编程,而不对具体编程,因为抽象相对稳定。
让类依赖于固定的抽象,所以修改就是封闭的;而通过面向对象的继承和多态机制,
又可以实现对抽象类的继承,通过覆写其方法来改变固有行为,实现新的拓展方法,所以就是开放的。
“需求总是变化”没有不变的软件,所以就需要用封闭开放原则来封闭变化满足需求,
同时还能保持软件内部的封装体系稳定,不被需求的变化影响。
※依赖倒置原则:依赖抽象,不要依赖具体。
抽 象的稳定性决定了系统的稳定性,因为抽象是不变的,依赖于抽象是面向对象设计的精髓,
也是依赖倒置原则的核心。依赖于抽象是一个通用的原则,而某些时候依 赖于细节则是在所难免的,
必须权衡在抽象和具体之间的取舍,方法不是一层不变的。依赖于抽象,就是对接口编程,不要对实现编程。
※里氏代换原则:子类型必须能够替换到他们的父类型。
Liskov 替换原则,主要着眼于对抽象和多态建立在继承的基础上,因此只有遵循了Liskov替换原则,
才能保证继承复用是可靠地。实现的方法是面向接口编程:将公 共部分抽象为基类接口或抽象类,
通过ExtractAbstractClass,在子类中通过覆写父类的方法实现新的方式支持同样的职责。Liskov替 换原则能够
保证系统具有良好的拓展性,同时实现基于多态的抽象机制,能够减少代码冗余,避免运行期的类型判别。
※接口隔离原则:多个和客户相关的接口要好于一个通用接口。
分离的手段主要有以下两种:1、委托分离,通过增加一个新的类型来委托客户的请求,隔离客户和接口的直接依赖,
但是会增加系统的开销。2、多重继承分离,通过接口多继承来实现客户的需求,这种方式是较好的。
下边是前面没有提到过的两个原则,也是设计时要考虑的重要原则。
※迪米特法则:不相互直接通信的类之间,不要直接发生相互作用。
如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用。如果一个类需要调用领一个类的
某个方法话,可以通过第三者转发这个调用。迪米特法则首先强调的前提是在类的设计上,每一类都应当尽量
降低成员的访问权限。它的根本思想是强调类之间的松耦合。
※合成/聚合复用原则:尽量使用合成/聚合,尽量不要使用继承。
合 成(Composition)和聚合(Aggregation)都是关联的特殊种类,聚合表示一种弱的拥有关系;
合成这是一种强的拥有关系,体现了严格的部分和整体的关系,部分和整体的生命周期一样。
优先使用合成或聚合原则将有助于保持每个类被封装,并被集中在单个任务上。这样类和类继承
层次会保持较小规 模,并且不太可能增长为不可控制的庞然大物。
OO设计基本原则的更多相关文章
- SOLID (面向对象设计) 基本原则
SOLID (面向对象设计) 基本原则 在 程序设计领域, SOLID (单一功能.开闭原则.里氏替换.接口隔离以及依赖反转)是由罗伯特•C•马丁在21世纪早期[1] 引入的记忆术首字母缩略 ...
- OO设计
Todd.log - a place to keep my thoughts on programming 评OO设计 昨天在微博上看到InfoQ提供了一本新书<完美软件开发:方法与逻辑> ...
- OO设计原则 -- OO设计的原则及设计过程的全面总结
这部分增加一点自己的感想,OO设计原则下面讲述的很清晰;看完之后有点感想如果我们在实际开发当中能够把这些原则熟烂于心的话那我们的代码质量和个人能力会有很显著的提神.根据自己的实际经验看很多开发者在开发 ...
- 常用的OO设计原则
常用的OO设计原则: 1 封装变化:找出应用中可能需要变化之处,把它们独立出来,不要和哪些不需要变化的代码混在一起. 2 针对接口编程,而不是针对实现编程. 3 多用组合,少用继承. 4 松耦合:为了 ...
- mysql优化-数据库设计基本原则
mysql优化-数据库设计基本原则 一.数据库设计三范式 第一范式:字段具有原子性 原子性是指数据库的所有字段都不可被再次划分,如下表就不满足原子性,起点与终点 字段就可被拆分为起点与终点两个字段. ...
- 动态变化的OO设计
今天看到个题目:对象会动态的变化. 游戏精灵,有人和神仙,但是随着人的不断积分,会升级为神仙:神仙也可能会因为积分的减少而降级为人.这种情况怎么画出个类图来. 这是第一版的设计,正常思维.人和神仙都是 ...
- HIS系统患者实体OO设计的一点思考
软件开发的生命周期中,数据库建模后,在某个数据库系统中形成相对应的表,之后再根据数据库模型设计相关的业务对象及其关系.这其实是进行了两次设计,一次是数据库模型设计,数据库模型设计是根据现实业务提取出来 ...
- RESTful API设计基本原则
REST四个基本原则:1.使用HTTP动词:GET POST PUT DELETE:2.无状态连接,服务器端不应保存过多上下文状态,即每个请求都是独立的:3.为每个资源设置URI:4.通过XML JS ...
- OO设计原则
开闭原则(OCP) 里氏代换原则(LSP) 依赖倒转原则(DIP) 接口隔离原则(ISP) 合成/聚合利用原则(CARP) 迪米特法则(LOD)
随机推荐
- C3P0使用详解
定义: C3P0是一个开源的JDBC连接池,目前使用它的开源项目有Hibernate,Spring等. 数据库连接池的基本思想就是为数据库连接建立一个"缓冲池".预先在缓冲池中放入 ...
- L131
Fake, Low Quality Drugs Come at High CostAbout one in eight essential medicines in low- and middle-i ...
- Java与数据库数据类型对应表
Java中的数据类型和SQL中的数据类型有很多不一样,需要仔细区分,不然易在开发中造成莫名的错误. Java数据类型 hibernate数据类型 标准SQL数据类型(PS:对于不同的DB可能有所差异) ...
- Ruby on Rails入门——macOS 下搭建Ruby Rails Web开发环境
这里只介绍具体的过程及遇到的问题和解决方案,有关概念性的知识请参考另一篇:Ruby Rails入门--windows下搭建Ruby Rails Web开发环境 macOS (我的版本是:10.12.3 ...
- Android内存优化(一)DVM和ART原理初探
相关文章 Android内存优化系列 Java虚拟机系列 前言 要学习Android的内存优化,首先要了解Java虚拟机,此前我用了多篇文章来介绍Java虚拟机的知识,就是为了这个系列做铺垫.在And ...
- UltraEdit编码设置
1.查看ue文件编码 一直苦于无法判断文件的编码类型,现在发现一个方法,就是用强大的UltraEdit-32软件: UltraEdit-32的状态栏可以显示文件的编码类型,详细情况如下: ANSCI- ...
- 推荐使用typora
最近在网上接触到一款全新的markdown写作工具--typora. 现在它已经是我的主要写作工具了. 甚至我也也会利用它安排自己的工作和任务. typora介绍 下载链接 特色:可以即时渲染mark ...
- (三)canvas绘制样式
beginPath() 对画线点的一个开始限制 moveTo() 画线的起点,只在开头使用 参数两个x轴,y轴 lineTo() 后续连线 两个参数x轴,y轴 stroke() 连线无填充 fill( ...
- 关于15桥梁课程1&2的笔记以及待做事项的梳理
1.指针所占用的空间是固定的 2.void *malloc(sizeof(int)); (这玩意耗时间,老师说通过内存池解决) free(p);free(p); 两次free()报错,正确的做法: ...
- Oracle Sql Developer 连接 SqlServer
1.下载 jTDS - SQL Server and Sybase JDBC driver 地址:http://sourceforge.net/projects/jtds/files/ 2.运行SQL ...