@TOC面向对象六大设计原则

最近准备java面试,发现SSM框架里蛮多知识点,比如Spring中IOC,DI来源于面向对象的六大原则,了解六大原则有助于更深入理解java的设计原理。网上资料很多,整理下六大设计原则,总结如下:
原作者博客链接1
原作者博客链接2

一.单一职责原则(SRP)

原文链接
单一职责原则,英文缩写SRP,全称Single Responsibility Principle。

原始定义:There should never be more than one reason for a class to change。

官方翻译:应该有且仅有一个原因引起类的变更。简单点说,一个类,最好只负责一件事,只有一个引起它变化的原因

原理解释
上面的定义不难理解,引起类变化的原因不能多于一个。也就是说每一个类只负责自己的事情,此所谓单一职责。

我们知道,在OOP里面,高内聚、低耦合是软件设计追求的目标,而单一职责原则可以看做是高内聚、低耦合的引申,将职责定义为引起变化的原因,以提高内聚性,以此来减少引起变化的原因。

其实在软件设计中,要真正用好单一职责原则并不简单,因为遵循这一原则最关键的地方在于职责的划分,(博主的理解是)职责的划分是根据需求定的,同一个类(接口)的设计,在不同的需求里面,可能职责的划分并不一样

总结

没有最合理,只有最合适。理解单一职责原则,最重要的就是理解职责的划分,职责划分的粒度取决于需求的粒度,最后又回到了那句话:没有最好的设计,只有最适合的设计。

二.开闭原则(OCP)

原文链接
开闭原则,英文缩写OCP,全称Open Closed Principle。

原始定义:Software entities (classes, modules, functions) should be open for extension but closed for modification。

字面翻译:软件实体(包括类、模块、功能等)应该对扩展开放,但是对修改关闭

原理解释

  • 对扩展开放。模块对扩展开放,就意味着需求变化时,可以对模块扩展,使其具有满足那些改变的新行为。换句话说,模块通过扩展的方式去应对需求的变化
  • 对修改关闭。模块对修改关闭,表示当需求变化时,关闭对模块源代码的修改,当然这里的“关闭”应该是尽可能不修改的意思,也就是说,应该尽量在不修改源代码的基础上面扩展组件

为什么要“开”和“闭”

一般情况,我们接到需求变更的通知,通常方式可能就是修改模块的源代码,然而修改已经存在的源代码是存在很大风险的,尤其是项目上线运行一段时间后,开发人员发生变化,这种风险可能就更大。所以,为了避免这种风险,在面对需求变更时,我们一般不修改源代码,即所谓的对修改关闭。不允许修改源代码,我们如何应对需求变更呢?答案就是我们下面要说的对扩展开放。

通过扩展去应对需求变化,就要求我们必须要面向接口编程,或者说面向抽象编程。所有参数类型、引用传递的对象必须使用抽象(接口或者抽象类)的方式定义,不能使用实现类的方式定义;通过抽象去界定扩展,比如我们定义了一个接口A的参数,那么我们的扩展只能是接口A的实现类。总的来说,开闭原则提高系统的可维护性和代码的重用性。

总结

细心的朋友可能觉察到了,以面向抽象编程的方式去达到对扩展开放的目的,这和我们的依赖倒置原则(高层模块不应该依赖低层模块,两者都应该依赖其抽象)怎么这么像。可能又朋友就要不满了,不就是一个面向抽象编程,玩这么多花样干嘛,将简单的问题复杂化。博主的理解是这些设计原则没有绝对的界限,它们只是从不同的侧重点去约束我们的软件架构,使其能使用各种不同的需求。

三.接口隔离原则(ISP)

官方定义

接口隔离原则,英文缩写ISP,全称Interface Segregation Principle。

原始定义:Clients should not be forced to depend upon interfaces that they don’t use,还有一种定义是The dependency of one class to another one should depend on the smallest possible interface。

官方翻译:

  • 不应该强行要求客户端依赖于它们不用的接口;
  • 类之间的依赖应该建立在最小的接口上面。简单点说,客户端需要什么功能,就提供什么接口,对于客户端不需要的接口不应该强行要求其依赖;类之间的依赖应该建立在最小的接口上面,这里最小的粒度取决于单一职责原则的划分。
  • 使用多个专门的接口,而不使用单一的总接口,即客户端不应该依赖那些它不需要的接口。

原理解释

  • 不应该强行要求客户端依赖于它们不用的接口。语句很好理解,即客户端需要什么接口,就依赖什么接口,不需要的就不依赖。那么我们反过来说,如果客户端依赖了它们不需要的接口,那么这些客户端程序就面临不需要的接口变更引起的客户端变更的风险,这样就会增加客户端和接口之间的耦合程度,显然与“高内聚、低耦合”的思想相矛盾。
  • 类之间的依赖应该建立在最小的接口上面。何为最小的接口,即能够满足项目需求的相似功能作为一个接口,这样设计主要就是为了“高内聚”。那么我们如何设计最小的接口呢?那就要说说粒度的划分了,粒度细化的程度取决于我们上一章讲的的单一职责原则里面接口划分的粒度。从这一点来说,接口隔离和单一职责两个原则有一定的相似性。

接口隔离原则和单一职责原则

从功能上来看,接口隔离和单一职责两个原则具有一定的相似性。其实如果我们仔细想想还是有区别的。

  1. 从原则约束的侧重点来说,接口隔离原则更关注的是接口依赖程度的隔离,更加关注接口的“高内聚”;而单一职责原则更加注重的是接口职责的划分。
  2. 从接口的细化程度来说,单一职责原则对接口的划分更加精细,而接口隔离原则注重的是相同功能的接口的隔离。接口隔离里面的最小接口有时可以是多个单一职责的公共接口。
  3. 单一职责原则更加偏向对业务的约束,接口隔离原则更加偏向设计架构的约束。这个应该好理解,职责是根据业务功能来划分的,所以单一原则更加偏向业务;而接口隔离更多是为了“高内聚”,偏向架构的设计。

依赖倒置原则(DIP)

依赖倒置原则,英文缩写DIP,全称Dependence Inversion Principle。

原始定义:High level modules should not depend upon low level modules. Both should depend upon abstractions. Abstractions should not depend upon details. Details should depend upon abstractions。

官方翻译:高层模块不应该依赖低层模块,两者都应该依赖其抽象;抽象不应该依赖细节,细节应该依赖抽象。

什么是依赖倒置原则?

推荐个非常好的文章

什么是依赖倒置原则? 假设我们设计一辆汽车:先设计轮子,然后根据轮子大小设计底盘,接着根据底盘设计车身,最后根据车身设计好整个汽车。这里就出现了一个“依赖”关系:汽车依赖车身,车身依赖底盘,底盘依赖轮子。
这样的设计看起来没问题,但是可维护性却很低。假设设计完工之后,上司却突然说根据市场需求的变动,要我们把车子的轮子设计都改大一码。这下我们就蛋疼了:因为我们是根据轮子的尺寸设计的底盘,轮子的尺寸一改,底盘的设计就得修改;同样因为我们是根据底盘设计的车身,那么车身也得改,同理汽车设计也得改——整个设计几乎都得改!

我们现在换一种思路。我们先设计汽车的大概样子,然后根据汽车的样子来设计车身,根据车身来设计底盘,最后根据底盘来设计轮子。这时候,依赖关系就倒置过来了:轮子依赖底盘, 底盘依赖车身, 车身依赖汽车。

这时候,上司再说要改动轮子的设计,我们就只需要改动轮子的设计,而不需要动底盘,车身,汽车的设计了。

这就是依赖倒置原则——把原本的高层建筑依赖底层建筑“倒置”过来,变成底层建筑依赖高层建筑。高层建筑决定需要什么,底层去实现这样的需求,但是高层并不用管底层是怎么实现的。这样就不会出现前面的“牵一发动全身”的情况。

  • 高层模块不应该直接依赖于底层模块的具体实现,而应该依赖于底层的抽象。换言之,模块间的依赖是通过抽象发生,实现类之间不发生直接的依赖关系,其依赖关系是通过接口或抽象类产生的。

  • 接口和抽象类不应该依赖于实现类,而实现类依赖接口或抽象类。这一点其实不用多说,很好理解,“面向接口编程”思想正是这点的最好体现。

被“倒置”的依赖

相比传统的软件设计架构,比如我们常说的经典的三层架构,UI层依赖于BLL层,BLL层依赖于DAL层。由于每一层都是依赖于下层的实现,这样当某一层的结构发生变化时,它的上层就不得不也要发生改变,比如我们DAL里面逻辑发生了变化,可能会导致BLL和UI层都随之发生变化,这种架构是非常荒谬的!好,这个时候如果我们换一种设计思路,高层模块不直接依赖低层的实现,而是依赖于低层模块的抽象,具体表现为我们增加一个IBLL层,里面定义业务逻辑的接口,UI层依赖于IBLL层,BLL层实现IBLL里面的接口,所以具体的业务逻辑则定义在BLL里面,这个时候如果我们BLL里面的逻辑发生变化,只要接口的行为不变,上层UI里面就不用发生任何变化。

在经典的三层里面,高层模块直接依赖低层模块的实现,当我们将高层模块依赖于底层模块的抽象时,就好像依赖“倒置”了。这就是依赖倒置的由来。通过依赖倒置,可以使得架构更加稳定、更加灵活、更好应对需求变化。

依赖倒置的目的

上面说了,在三层架构里面增加一个接口层能实现依赖倒置,它的目的就是降低层与层之间的耦合,使得设计更加灵活。从这点上来说,依赖倒置原则也是“松耦合”设计的很好体现。

面向对象六大设计原则上相关推荐

  1. 【设计模式】 面向对象六大设计原则

    面向对象设计的六大原则 : 单一职责原则, 里氏替换原则, 依赖倒置原则, 接口隔离原则, 迪米特法则, 开闭原则; 一. 单一职责原则 1. 单一职责简介 单一职责定义 : 有且只有一个原因引起类的 ...

  2. 面向对象六大设计原则

    目录 1 .单一职责(Single Responsibility Principle) 2 .开闭原则(Open Close Principle) 3.里氏替换原则(Liskov Substituti ...

  3. 【0718作业】收集和整理面向对象的六大设计原则

    面向对象的六大设计原则 (1)单一职责原则--SRP (2)开闭原则--OCP (3)里式替换原则--LSP (4)依赖倒置原则--DIP (5)接口隔离原则--ISP (6)迪米特原则--LOD - ...

  4. [转] 设计模式的六大设计原则

    转载说明: 感谢原作者吕震宇老师的分享. 原文参考链接:https://www.cnblogs.com/zhenyulu/category/6930.html? 本次转载只用于个人学习使用,并不涉及商 ...

  5. 引用防删——JAVA设计模式总结之六大设计原则

    JAVA设计模式总结之六大设计原则 从今年的七月份开始学习设计模式到9月底,设计模式全部学完了,在学习期间,总共过了两篇:第一篇看完设计模式后,感觉只是脑子里面有印象但无法言语.于是决定在看一篇,到9 ...

  6. 设计模式之六大设计原则【入门】

    设计模式之六大设计原则 1 开闭原则 Open Closed Principle,OCP 1.1 概念 1.2 软件实体 1.3 开闭原则的作用 2. 单一职责原则 Single responsibi ...

  7. 设计模式必备知识点----六大设计原则

    六大设计原则 一,开闭原则 开闭原则的定义 什么是开闭原则 开闭原则的作用 开闭原则的优点 二,单一职责原则 单一职责定义 单一职责的作用 单一职责的优点 单一职责的违背原则 三,依赖倒置原则 依赖倒 ...

  8. 设计模式的六大设计原则

    设计模式的六大设计原则 1. 开闭原则 1.1 开闭原则:Open Closed Principle,OCP 1.2 开闭原则的作用 2. 单一责任原则 2.1 单一职责原则:Single respo ...

  9. 设计模式—六大设计原则

    本文开始对<设计模式之禅>进行学习总结,首先是六大设计原则. 单一职责原则 单一职责原则(Single Responsibility Principle)简称SRP,这个原则存在的争议之处 ...

最新文章

  1. Hat’s Words(字典树)
  2. MySQL的MVCC机制是什么?
  3. 自律到极致-人生才精致:第12期
  4. RabbitMQ 高可用之如何确保消息成功消费
  5. Spring系列之一 Spring MVC
  6. es6新语法Object.assign()
  7. 数据库概念 MySQL 库操作 表操作 记录操作
  8. django2连接mysql_django2连接mysql
  9. 玩转大数据系列之一:数据采集与同步
  10. 空间变量php,PHP名称空间可以包含变量吗?
  11. 多媒体技术及应用课后习题
  12. mysql 合服_风云私服合区的方法详解(mysql数据库合并)
  13. 深度学习:YOLO算法与其优化
  14. 基于JAVA的教务排课系统.rar(源码+截图+数据库)
  15. 浅谈对于机器学习的理解
  16. 设CPU共有16根地址线,8根数据线,并用MREQ (低电平有效) .作访存控制信号,R/W作读写命令信号(高电平为读,,低电平为写)。
  17. OSChina 周二乱弹 —— 她根本就配不上我这么聪明的男人
  18. 衷心感谢各位给我投的票!
  19. VC dll 注入之钩子注入
  20. 哈希表_四数之和(待完善)

热门文章

  1. Javascript与Jquery知识点
  2. pythondocx模板_Python-Word模板填充-docxtpl
  3. 【行研报告】2021办公物业管理发展报告—附下载
  4. JavaSE第一阶段知识概括
  5. ps学习笔记2(修复无损、水印等方法)
  6. 校招实习面试实战,顺丰科技Java工程师面试复盘总结
  7. Java SE基础:计算机组成与Java概述
  8. 仿支付宝支付成功控件
  9. 粮食储备库电力配电监控系统的设计与应用
  10. 3D视觉(五):对极几何和三角测量