软件设计漫谈之三:30分钟掌握面向对象类的设计原则-阿里云开发者社区

开发者社区> 华仔爱技术> 正文

软件设计漫谈之三:30分钟掌握面向对象类的设计原则

简介:
+关注继续查看

                            30分钟掌握面向对象类的设计原则

看过设计模式的人不少,但看过Martin的面向对象的设计原则的估计不多(详情可参考《敏捷软件开发:原则、模式与实践》)。实际上这两者是相辅相成的:设计模式是具体的实践方法,而设计原则是指导思想;设计模式让你知道How,而设计原则让你知道Why

《敏捷软件开发:原则、模式与实践》原著洋洋洒洒几十万言,介绍面向对象类的类的设计几个原则也有几十页,没有耐心的朋友估计看不下去。没关系,这里我给大家一个精简版的,让你读完本博就能够初步掌握这些原则,而且附送一些疑难解答,让你更加容易理解。

1                 SRP(单一职责原则)

这个原则看起来很简单,就是说一个类只能承担一个职责

但这里有一个关键:“职责”是如何理解的?

按照汉语的理解,职责其实分为两部分:“职”和“责”。“职”就是这个类是什么,而“责”就是这个类要干什么

举个例子来说:Door是一个对象,那么它的“职”就是门,“责”就是“开门、关门”等;而Lock的“职”就是锁,“责”就是“上锁、开锁”。如果设计的时候Door同时具有锁的职责,那么Door就违反了SRP原则。

2                 OCP(开闭原则)

相信这是大家见得最多的原则,而且很多人都是这么解释的“对扩展开放、对修改封闭”,更加有人总结为“不修改代码增加新的功能”!

太神奇了,不修改代码增加新的功能!但我不免疑惑:不修改代码怎么增加新的功能呢?难道代码会像生物一样,基因变异?

仔细研究过后才发现,原来是这些总结的人误导了我,根本不是什么“不修改代码增加新的功能”,也不是那个省略了主语的“对扩展开放,对修改封闭”,而是“被调用者开放扩展,调用者封闭修改

还是举门的例子:Door对象是被其它对象例如人People调用,那么Door就是被调用者,People就是调用者。Door对象可以扩展为“防盗门”、“防火门”、“逃生门”等,但People在调用的时候不需要关注具体是什么门,只需要调用这些门公共的“开门、关门”等操作即可。

3                 LSP Liskov替换原则)

这个看起来是比较难理解的原则,但我可以给一个很容易理解的总结:“子类的输入不能比父类多,子类的输出不能比父类少!”。

“输入”就是指调用类的时候要给出的条件,最常见的就是函数参数,而一般的语言都可以从语法上保证这种子类和父类相同函数的参数必须相同;还有另外一种隐性的条件即“假设”或者“要求”也必须相同。

举个简单的例子:长方形和正方形。按照数学的定义,正方形是特殊的长方形。依照此定义看起来好像可以将正方形定义为长方形的子类,但实际上在面向对象设计中则是不行的,因为按照设定长方形长宽的方法不能来设定正方形的边长,正方形要求长宽必须相等,而长方形没有此“要求”。这就是子类的“假设”或者“假设”多于父类,违反了LSP原则。

“输出”就是指调用类后返回的结果。即:子类的返回结果要包含父类的返回结果,可以多但绝对不能少。

为什么设计时要满足LSP原则呢?其实很简单,因为调用者看到的只有父类,它根本不知道到底是哪个子类,调用者所有的处理都是基于父类提供给调用者的信息(包括输入信息和输出信息)。

4                 DIP(依赖反转原则)

这个原则看起来有点吓人,换个简单的说法你就明白了,其实它就对应于《设计模式》开头提到的两个原则中的一个:“基于接口编程,而不是基于实现编程”。(另外一个是什么呢?)

这里的“编程”包括“调用者”和“被调用者”的编程。“调用者”基于接口进行调用,“被调用者”基于接口进行具体实现。

注意:和“依赖反转”类似的两个比较容易混淆的概念是“依赖注入”和“控制反转”,详细可以参考如下博文:http://blog.csdn.net/taijianyu/archive/2008/04/28/2338311.aspx

5                 ISP(接口隔离原则)

这个原则也很简单,就是说一个对象不要提供多个接口,不同的接口应该分离到不同的对象上去。

虽然大师的水平不容怀疑,但这里我还是要怀疑一下:SRPISP本质上应该是一个原则,只是说法不一样而已

为什么这么说呢?大家可以看看SRP原则,它说的是“单一职责”。那么职责最终体现在对象上是什么呢?对,不就是接口么!也就是说,如果遵循了SRP原则,接口自然就隔离了。

 

================================================ 

怎么样,看到这里是否只花了30分钟?那么这些原则你是否基本都掌握了呢?如果还有什么疑问,欢迎留言讨论。

 

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
带你读《存储漫谈Ceph原理与实践》第三章接入层3.2对象存储RGW(二)
《存储漫谈Ceph原理与实践》第三章接入层3.2对象存储RGW
27 0
让外卖小哥15分钟训练出AI模型的深思平台,如何让传统企业轻松拥抱AI?
令人意想不到的是,一位外卖小哥用名为深思的AI平台在15分钟内就训练出了一个准确率99%以上的AI模型。
282 0
三分钟带你认识注解 | 带你学《Java面向对象编程》之四十五
本节将为读者介绍JDK1.5之后诞生的新特性-注解式编程方式,并为读者深度剖析其出现的价值与意义。
566 0
1分钟体验代码自动捉虫,Cherry键盘、积木星球抱回家
如今,一款软件的开发往往需要多成员协作开发。 随着人员规模的扩大,如何保证代码的质量和安全,仅靠成员自觉自测,一是花时间,二是质量上难免参差不齐、无法形成统一的流程规范。 引入自动化的代码检测工具,在代码提交时自动检测代码里的缺陷、漏洞等,设定质量卡点等,可以有效提升团队代码的质量和安全,把DevSecOps落到实处。
487 0
《存储漫谈Ceph原理与实践》第三章接入层3.2对象存储RGW(一)
《存储漫谈Ceph原理与实践》第三章接入层3.2对象存储RGW
31 0
【愚公系列】2021年12月 面向对象设计原则(六)-合成复用原则(Composite Reuse Principle or CRP)
【愚公系列】2021年12月 面向对象设计原则(六)-合成复用原则(Composite Reuse Principle or CRP)
22 0
《存储漫谈Ceph原理与实践》第三章接入层3.2对象存储RGW(四)
《存储漫谈Ceph原理与实践》第三章接入层3.2对象存储RGW
17 0
面象对象设计6大原则之三:里氏替换原则
里氏替换原则(LSP),The Liskov Substitution Principle 定义 所有引用基类的地方必须能透明地引用其子类的对象,即子类可以拓展父类的功能,但不能修改父类已有的功能。
880 0
+关注
华仔爱技术
热爱技术的10多年IT老兵,既能深入底层写代码,又能高屋建瓴做架构;可以带领团队往前冲,也能侃侃而谈做演讲。著有《面向对象葵花宝典:思想、技巧与实践》。
114
文章
1
问答
文章排行榜
最热
最新
相关电子书
更多
《2021云上架构与运维峰会演讲合集》
立即下载
《零基础CSS入门教程》
立即下载
《零基础HTML入门教程》
立即下载