Bob大叔观OO原则
Bob大叔观OO原则
上篇总结了经典的23种 设计模式,详细的解读后期会陆续的详细揭开。使用设计模式的根本原因就是为了增强代码的复用性和可维护性。而面向对象是实现代码复用的有效途径,所以这里有必要了解一下OO的基本思想和原则。
面向对象设计的原则(OOD&OOP)主要分为两大类,一类是面向类的,另一类是面向包的。设计模式基本都是围绕面向类的几个原则的实践,而面向包的几个原则主要体现在架构模式中。
S.O.L.I.D
Bob大叔(Robert C. Martin)的大名如雷贯耳,相信大部分在进击中的开发者都有阅读过经典著作《敏捷软件开发》的经历,受益匪浅。
在面向对象的程序的设计和开发过程中时,有5个原则非常重要,此外还有一个法则我们应该尽量去遵守它。
1、单一职责原则(SRP,The Single Responsibility Principle)
2、开放封闭原则(OCP,The Open Closed Principle)
3、里氏替换原则(LSP,The Liskov Substitution Principle)
4、依赖倒置原则(DIP,The Dependency Inversion Principle)
5、接口分离原则(ISP,The Interface Segregation Principle)
6、迪米特法则(LoD,The Law of Demeter、LKP)
SRP
A class should have only one reason to change.
一个类应该仅有一个引起它变化的原因。
SRP是所有原则中最简单的一个,概念简洁易懂。但却也是最难正确运用,或者说是最容易过度使用的原则。
一方面,因为SRP把职责定义成了变化的原因,如果我们能够找到多于一个的动机去改变一个类,那么这个类就具有多于一个的职责。比如开发者经常会习惯性的把职责归类式的结合在一起,而正确的做法是发现职责并把这些职责相互分离。
另一方面,如果程序的变化方式总是导致N个职责(N>1)同时变化,那么就没必要分离它们了。在这里有一个推论:仅当变化发生时,变化的轴线才具有实际的意义。在实际的设计和开发过程中,一定要把握好分离“单个”职责的度,所谓过犹不及,过度的分离只能适得其反,违背了面向对象的封装思想。
OCP
Software entities(classes,modules,functions,etc.) should be open for extension, but closed for modification.
软件实体(如类、模块、函数等)应该对扩展开放,对修改关闭。
OCP是整个面向对象设计的核心。它代表了灵活性、可重用性和可维护性。
乍一看,两个特征似乎有所矛盾,扩展模块的功能通常是以修改模块的源代码作为手段。但是,我们有“抽象”!通过创建稳定的但又能描述一组任意个可能行为的抽象基类,并将具体的行为实现为派生类,这种做法能很好的解决开放扩展的问题。主要是针对软件中频繁变化的那部分作出合理的抽象。
当然,创建和使用抽象会增加软件复杂性和团队的精力,所以肆意的进行抽象显然并不是一个好设计,简直是折磨人。除非你有强大的智商优越感,但是面对广大平凡质朴的程序员,还请手下留情。
拒绝不成熟的抽象和抽象本身一样重要。
LSP
Derived types must be completely substitutable for their base types.
子类型必须能够完全的替换掉它们的基类型。
LSP是使OCP成为可能的主要原则之一,也是继承层次特征的主要设计原则。
一个软件实体如果使用的是一个父类的话,那么一定适用于其子类,而且它察觉不出父类对象和子类对象的区别。也就是说,在软件中,把父类都替换成它的子类,程序行为没有或者不发生变化。也就是说,只有当子类可以替换掉父类,软件的功能不受到影响时,父类才能真正的被复用,而子类也能够真正的在父类的基础上增加新的行为。
子类型的可替换性使得使用基类型表示的模块在无需修改的情况下就可以扩展。可替换性可以通过显示或者隐式的契约来定义。
DIP
A. High-level modules should not depend on low-level modules. Both should depend on abstractions.
高层模块不应该依赖于低层模块,两者都应该依赖于抽象
B. Abstractions should not depend on details. Details should depend on abstractions.
抽象不应该依赖于细节,细节应该依赖于抽象
DIP是面向对象设计的标志。
依赖倒置原则是实现许多面向对象技术所宣称的好处的基本低层机制,他的正确应用对于创建可重用的框架来说是必须的。同时它对于构建在变化面前富有弹性的代码也是非常重要的,由于抽象和细节彼此隔离,所以代码也非常容易维护。
针对接口编程,而不要对实现编程。倒置接口的所有权。
LSP和DIP乍一看还有点相似,其实,他们还是有区别的:
两个原则所站的角度不同。LSP是站在模式对象的角度,而DIP则是站在客户端程序的角度;模式对象一方将“相对多变的”子类视同它的接口(或父类),而客户程序依赖的内容是“相对稳定”的接口。
ISP
Clients should not be forced to depend upon interfaces that they don't use.
不应该强迫客户程序依赖并未使用的接口。
ISP有效的降低了程序间的耦合性,提高了程序集的内聚性。避免了接口污染。
客户程序应该仅仅依赖于他们实际调用的方法。分离客户就是分离接口。通常我们可以使用委托或者使用多重继承来分离接口。
接口隔离原则不是单纯的多余或是不多余,从设计的角度来衡量,它要依据业务领域的需要判断倒是是否真的“多余”,确保在每个领域背景下贯彻不去依赖用不到的方法。通过把胖类的接口分解为多个特定于客户程序的接口,可以实现这个目标。有效的解除了客户程序和它们没有调用到的方法间的依赖关系。
客户程序看到的应该是多个具有内聚接口的抽象基类。
LoD(LKP)
A. Each unit should have only limited knowledge about other units: only units "closely" related to the current unit.
每一个软件单位对其他的单位都只有最少的知识,而且局限于那些与本单位密切相关的软件单位。
B. Each unit should only talk to its friends; don't talk to strangers.
C. Only talk to your immediate friends.
迪米特法则又称为最少知识原则。主要有三层意思,就是让调用者对于目标对象的知识最少,而且只和你的直接朋友对话,千万不要和陌生人说话。
该法则因在《程序员的修炼之道》一书中提及而声名鹊起广为人知。其初衷在于降低类之间的耦合,但是由于通过友元类来建立一个类和其他类的联系,或是减少对其他类的依赖,这导致了在一定程度上增加了系统的复杂度。
小结
这些原则是数十年软件工程经验来之不易的结果。是众多开发人员和研究人员思想和著作的结晶。我们应该牢记面向对象设计的原则,理解OO的设计思路。因为它们有助于开发人员消除拙劣的设计和代码臭味,并能有效的帮助开发人员构建出最适合于当前特性集的设计。
Bob大叔建议:在日常工作中,只有当出现“臭味”时我们才会去使用它,如果只是因为它是一个原则就无条件的遵循它那是错误的,过分的遵循这些原则会导致不必要的复杂性和设计臭味。
个人认为,一切均应切合实际,要考虑到团队的承受能力,项目的可控范围等等因素。
不要把它当作可以在系统中随意喷洒的香水!
结尾:上面主要记述了面向类(对象)的几个设计模式原则,后续会论述面向包设计的架构模式原则 。
Bob大叔观OO原则的更多相关文章
- 跟Bob大叔观OO原则
上篇总结了经典的23种 设计模式,详细的解读后期会陆续的详细揭开.使用设计模式的根本原因就是为了增强代码的复用性和可维护性.而面向对象是实现代码复用的有效途径,所以这里有必要了解一下OO的基本思想和原 ...
- [翻译]Bob大叔:反思极限编程
译者注: Bob大叔14年后再次谈论极限编程.极限编程经历了14年的风风雨雨后,Bob大叔将会给它怎么样的定义那? 在我手中拿着的一本白皮薄书,在14年前彻底的改变了软件世界.这本书的标题是解析极限编 ...
- oo原则
基本原则: 封装变化Encapsulate what varies. 面向接口编程而非实现 Code to an interface rather than to an implementation. ...
- OO原则汇总
SOLID原则:http://www.cnblogs.com/lanxuezaipiao/archive/2013/06/09/3128665.html https://www.cnblogs.com ...
- 对OO原则的个人理解
1.单一职责原则.(Single Responsibility Principle) 注解:社会化大生产分工要细.具体每个人最好只做一件事(不要一人兼多职),这样如果这个人请假或辞职,对生产不会产生影 ...
- 翻译 | The Principles of OOD 面向对象设计原则
本文首发于vivo互联网技术微信公众号 https://mp.weixin.qq.com/s/Q_pziBUhKRywafKeY2T7YQ 作者:Robert C. Martin 翻译:张硕 本文由来 ...
- OO之美2
面向对象并没有想象中那么神秘,以生活的现实眼光来看更是如此.把面向对象深度浓缩起来,可以概括为: ⑴目标:重用,扩展,兼容 ⑵核心:低耦合,高内聚 ⑶手段:封装变化 ⑷思想:面向接口编程,面向抽象编程 ...
- 老调重弹--面向对象设计原则--S.O.L.I.D设计原则
SRP - 单一职责原则 全称:Single Responsibility Principle 定义:每一个上下文对象(类.函数.变量等等)的定义应该仅仅包含单一的职责 描述:对象提供单一职责的高度封 ...
- S.O.L.I.D五大原则之单一职责SRP
转自 : 汤姆大叔的blog Bob大叔提出并发扬了S.O.L.I.D五大原则,用来更好地进行面向对象编程,五大原则分别是: The Single Responsibility Principle(单 ...
随机推荐
- C语言获取文件SHA1哈希
安全散列算法(Secure Hash Algorithm)主要适用于数字签名标准 (Digital Signature Standard DSS)它定义了数字签名算法(Digital Signatur ...
- JavaScript语言基础知识10
JavaScript中间if声明: <span style="font-size:18px;"><HTML> <HEAD> <TITLE& ...
- HOJ2275 Number sequence
Number sequence My Tags tag=&type=or" style="margin:0px; padding:0px; color:rgb(27,87, ...
- Linux使用快捷键,who命令,rm命令,ps命令,cd,命令kill命令,find命令,grep命令,tar命令(gz、tar、bz2),用户管理,vim配置的一部分,相关命令
1.进入Ubuntu开场后的终端窗口的快捷键是: ctrl + alt+t:通过这个命令能够打开终端. ctrl + alt+t:通过这个命令能够打开终端. 再开一个tab选项卡式 ...
- 故障排查:是什么 导致了服务器端口telnet失败?(转)
telnet命令的主要作用是与目标端口进行TCP连接(即完成TCP三次握手).当服务端启动后,但是telnet其监听的端口,却失败了.或者,当服务端运行了一段时间后,突然其监听的端口telnet不通了 ...
- win8.1 64位环境建设android开发环境
1.下载JDK,http://www.oracle.com/technetwork/java/javase/downloads/index.html,选择版本号 2.安装刚刚下载的JDK 3.环境变量 ...
- Sqlserver中Over函数
Over函数不能单独使用,要和分析函数:rank(),dense_rank(),row_number()等一起使用. 其参数:over(partition by columnname1 order ...
- POJ 2538 WERTYU水的问题
[题目简述]:题意非常easy,没有trick. [分析]:事实上这题还是挺有趣的,在 算法竞赛入门经典中也有这一题. 详见代码: // 120K 0Ms /* 边学边做 -- */ // 字符串:W ...
- ExtJs迄今datefield控制设置默认值
假设extjs4 datefield日期控件设置默认值.为当天的前一月,和后一月 Ext.Date.MONTH 月 Ext.Date.YEAR 年 Ext.Date.DAY ...
- 理解和运用javascript中的call及apply
call是为了改变函数上下文context而存在的,换言之,就是改变函数内部this的指向.因为javascript存在[定义时上下文],[运行时上下文]及[上下文]是可以改变的.例如:var fun ...