上篇总结了经典的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原则的更多相关文章

  1. Bob大叔观OO原则

    Bob大叔观OO原则 上篇总结了经典的23种 设计模式,详细的解读后期会陆续的详细揭开.使用设计模式的根本原因就是为了增强代码的复用性和可维护性.而面向对象是实现代码复用的有效途径,所以这里有必要了解 ...

  2. [翻译]Bob大叔:反思极限编程

    译者注: Bob大叔14年后再次谈论极限编程.极限编程经历了14年的风风雨雨后,Bob大叔将会给它怎么样的定义那? 在我手中拿着的一本白皮薄书,在14年前彻底的改变了软件世界.这本书的标题是解析极限编 ...

  3. oo原则

    基本原则: 封装变化Encapsulate what varies. 面向接口编程而非实现 Code to an interface rather than to an implementation. ...

  4. OO原则汇总

    SOLID原则:http://www.cnblogs.com/lanxuezaipiao/archive/2013/06/09/3128665.html https://www.cnblogs.com ...

  5. 对OO原则的个人理解

    1.单一职责原则.(Single Responsibility Principle) 注解:社会化大生产分工要细.具体每个人最好只做一件事(不要一人兼多职),这样如果这个人请假或辞职,对生产不会产生影 ...

  6. 翻译 | The Principles of OOD 面向对象设计原则

    本文首发于vivo互联网技术微信公众号 https://mp.weixin.qq.com/s/Q_pziBUhKRywafKeY2T7YQ 作者:Robert C. Martin 翻译:张硕 本文由来 ...

  7. OO之美2

    面向对象并没有想象中那么神秘,以生活的现实眼光来看更是如此.把面向对象深度浓缩起来,可以概括为: ⑴目标:重用,扩展,兼容 ⑵核心:低耦合,高内聚 ⑶手段:封装变化 ⑷思想:面向接口编程,面向抽象编程 ...

  8. 老调重弹--面向对象设计原则--S.O.L.I.D设计原则

    SRP - 单一职责原则 全称:Single Responsibility Principle 定义:每一个上下文对象(类.函数.变量等等)的定义应该仅仅包含单一的职责 描述:对象提供单一职责的高度封 ...

  9. S.O.L.I.D五大原则之单一职责SRP

    转自 : 汤姆大叔的blog Bob大叔提出并发扬了S.O.L.I.D五大原则,用来更好地进行面向对象编程,五大原则分别是: The Single Responsibility Principle(单 ...

随机推荐

  1. Sybase Unwired Platform(SUP) 经常使用资源整理(不断更新中)

    提示:建议刚開始学习的人看三个东西,详见以下的详细内容.然后再去看论坛,官方技术支持站点等资源. SUP移动开发平台 中文视频讲座 SUP入门讲座(Wang Jun) SUP系列学习笔记 SUP实验 ...

  2. EXE文件结构和读取方法

    一.EXE文件概念 EXE File英文全名executable file .译作可运行文件,可移植可运行 (PE) 文件格式的文件,它能够载入到内存中.并由操作系统载入程序运行,是可在操作系统存储空 ...

  3. MFC漆摘要-截图,获得DIB/DDB图形Pixel

    1.       当前Screen进行Copy屏幕,获得BITMAP 当前屏幕Copy.须要获取当前屏幕的HDC, 一种是直接从屏幕DC抓原始图. 一种是然后使用兼容MemDC进行抓图,然后能够附加图 ...

  4. 于iOS跳转到应用程序AppStore

    1.找到应用程序的叙述原文链接,实例: https://57324.api-01.com/serve? action=click&publisher_id=57324&site_id= ...

  5. [原创] linux deepin 2014.1下编译putty

    在网上找了很久,都没有找到linux下直接可以用的putty程序,最终在putty官网找到了源代码 点击下载 把源代码下载回来. 1.下载源代码 2.安装依赖库 如果系统中没有安装过libgtk2.0 ...

  6. 给EasyUI的DateBox控件添加清除button

     EasyUI中间DateBox控制甚至没有被清除button.例如下面的附图: 真是不可思议,对于要求日期格式必须选择的情况下,不能清空日期,很不方便.      尽管能够通过手工改动EasyU ...

  7. C# WinForm多线程(三)Control.Invoke

    下面我们就把在Windows Form软件中使用Invoke时的多线程要注意的问题给大家做一个介绍. 首先,什么样的操作需要考虑使用多线程?总的一条就是,负责与用户交互的线程(以下简称为UI线程)应该 ...

  8. 查看.a架构文件

    苹果公司现在要求所有新提交的评论app,我们必须支持64位架构.而我们的在线项目编制,操作员做了一堆SDK在需要访问,我们发现,在这个过程中,有些SDK的.a文件进入后,链接错误,如提示 Undefi ...

  9. Android访问设置

    在需求 AndroidManifest.xml 中增加下面代码: (1)假设应用程序须要訪问网络权限 <uses-permission android:name="android.pe ...

  10. HDU 4391 Paint The Wall 段树(水

    意甲冠军: 特定n多头排列.m操作 以下是各点的颜色 以下m一种操纵: 1 l r col 染色 2 l r col 问间隔col色点 == 通的操作+区间内最大最小颜色数的优化,感觉非常不科学... ...