1.开闭原则

很多教程都把开闭原则作为这六大原则中最基本的原则,也就是说他是各个原则的核心。开闭原则指的是,一个软件实体如类、模块和函数应该对扩展开放,对修改关闭

对于开闭原则,我们在设计软件的时候,首先要搞清楚程序当中什么是未来可能变化的,什么是未来不会变化的。对于可能变化的东西,我们要提前给与可以对应的扩展接口。当然实际开发中,即便是我们认为这些不会变化的地方,未来还是可能变化的,这种变化就只能改代码了,但是这种修改仅仅只是改变个别细节,整体架构往往不会变化。而对于可能变化的地方,我们要给出可以足够扩展的空间,让其能够自由扩展,基本发生了重大的需求变更,整体架构也不会受影响。

例如:工厂模式中,我们将创建对象的过程封装了起来,这样创建对象对的过程中,创建的代码就和调用的代码尽可能地解除了耦合。创建过程可能是变化的,而调用过程往往是不变的。我们创建一个对象之后,需要为其初始化,设定一些配置,这个过程需要我们给出可以扩展的余地,而且要求扩展的时候不能影响调用部分,所以需要使用工厂模式,将可变的创建过程封装起来,供不变的调用模块。

这样说来,开闭原则的核心是解耦了?没错,我认为开闭原则讲的就是解耦,但是他要求我们在设计的时候,重点要预判出什么地方是会发生变化的,并要为变化的地方留出余地。他强调的是对于可变部分进行解耦,使用扩展的方式而不是修改的方式应对变化,这样可以保证程序整体不会发生大的变化。

开闭原则对于开发框架、可以被复用的组件(如jar、dll、js插件等待)尤为重要,因为这些组件必须留出足够的空间去让调用者去扩展自己的业务。所以我们在开发这种组件的时候api才是最难设计的,因为我们设计的API必须能满足调用者对他的全部扩展,这样才能实现调用者在不修改组件代码的情况下实现自己的需求。

2.里氏替换原则

这个原则挺简单,讲的就使用接口的时候,我们必须确保子类能够替换父类所出现的任何地方。纯粹就字面的意思来讲,就是父类接口必须确保所有子类都可以实现需求,而不是某一个子类。

例如,java中HashMap和LinkedHashMap都是Map的子类。但是HashMap的顺序是随机的,而LinkedHashMap是固定的。当我们需要使用一个map,此map不需要要求key顺序可控的话,我们可以声明:

Map createMap(){

   return new HashMap();}

但我们要求顺序可控是,如果是这样:

Map createMap(){  

   return new LinkedHashMap();}

上述代码就不太好了,因为HashMap也是Map的一个子类,但是他不能满足我们的需求,所以此处必须声明返回值类型为LinkedHashMap。例如我们在设计接口的方法的时候,如果调用者需要的是一个LinkedHashMap,我们就不能以HashMap类型做接口的声明。

当然里氏替换原则也可以从设计角度出发,他强调我们设计的时候需要确保父类定义了的时候,就应该覆盖到这个接口抽象出的业务的所有方法,而不需要他的子类再添加额外的扩展,同时各个子类也都该实现父类中的所有接口,只有这样才能保证我们设计出的东西是可扩展的。

开闭原则讲究扩展,里氏替换原则可以确保通过继承这种方式的扩展是可行的,否则就无法使用继承去扩展程序了。

例如:我们使用模板模式,做了一个类作为父类算法模板,一个子类继承了这个模板,并且顺利地完成了运行;但是另一个子类也继承了模板类,却无法运行,最终发现程序无法确保所有继承模板的子类可以替换父类,这就是个失败的模板模式。

从面相对象的角度来说,里氏替换原则是子类可以替代父类,但是从面相组件的角度看,其实是确保组件的api是完整的、不变的,子类和外界也是完全解耦的,只有这样我们开发出的扩展才能在不破坏原有框架的基础上运行。

3.依赖倒置原则

这个原则也是讲究解耦,他指的是让高层模块不要依赖低层模块。这是个纯粹的面向接口,面向模块开发思路了,因为面向对象而言,各个对象自己的东西和外界是解耦的,因为封装特性把它们自己的属性都封装起来了,所以是不会和其他对象有耦合关系的(如c++的友元除外);但是各个对象仍然是相互耦合的,最强的耦合就属于继承耦合了,对象组合起码还是轻耦合,继承是个高耦合呀。依赖倒置就是让各个对象耦合度降低,高层模块不能继承底层模块,需要底层的东西也是外界注入而不是自己创建得到;同时调用的时候也是使用接口调用,而不是依赖具体实现,并且因为是接口调用,具体实现模块可以被任意替换了。

这样做就可以降低各个模块的耦合,也可以确保里氏替换原则的实现。实现里氏替换原则有什么用?当然是可以方便扩展了。

456.职责单一原则、接口隔离原则、最小知道原则(迪米特原则)

这几个原则很像,就放到一起说吧。这几个类都是在强调解耦(当然开闭原则、里氏替换原则、依赖倒置原则也是)。这几个原则基本都是强调解耦,只是站的角度不一样。职责单一原则指的是一个模块(接口)的功能尽量是单一的,这样不同功能的接口就不会耦合在一起了,同时维护起来也方便。接口隔离原则强调每个类继承的接口一定要保证最少,不能继承无用的接口,保证接口隔离原则的前提是先要保证职责单一原则。最后一个最小知道原则指的是模块是所有的依赖都要保证最少,这一点和接口隔离原则有点重复,或者可以说接最小知道原则包含接口隔离原则,同时最小知道原则还有对外界影响最小的意味。这几个原则说的都是类和接口设计要尽量降低耦合的问题。

总结:和设计模式的关系

简单介绍了一下这几大基本原则,再说说我对于他们和设计模式的理解。我们在学习设计模式的时候,有没有想过为什么要学习这个,学习了设计模式有什么好处?我在工作中经常发现很多经验欠缺的程序员,为了学习设计模式而学习设计模式,为了使用设计模式而使用设计模式,而有经验的程序员则不会这样。其实程序员开发的每一个程序都是从需求出发的,只有搞清楚我们一个项目的根本需求才有使用设计模式的意义。

六大原则中,最重要的肯定就是开闭原则了,我对开闭原则的理解是,你无须在每个细节上都要做到对扩展开放,对修改关闭,而是应该为了面对扩展而扩展。当有这种需求的时候,例如一个项目业务、算法可能会有重大的变化,或者本身开发的就是一个组件,这是才需要扩展,而扩展的时候才应该使用设计模式来实现这种需求,也就是说使用设计模式和我们平时开发一样,都是满足需求。

使用了设计模式不一定能真正地提高代码的结构和可维护性,所以有经验的程序员会按需求而使用设计模式。六大基本原则可以更好地帮我们如何分析,这样才能确定是否使用设计模式。事实上设计模式的使用上我建议无招胜有招,满足项目的额外需求(例如利于扩展、可复用、高可维护性)都是好招,无需管他是什么设计模式。

面向对象六大基本原则相关推荐

  1. 学习设计模式 - 六大基本原则之开闭原则

    设计模式总共有六大基本原则,统称为SOLID (稳定)原则,分别是S-单一职责原则(Single Responsibility Principle), O-开闭原则(Open closed Princ ...

  2. Java开发的六大基本原则

    文章目录 1.单一职责原则 2.开放封闭原则 3.里氏替换原则 4.接口隔离原则 5.依赖倒置原则 6.迪米特原则 设计模式之禅 Java开发六大基本原则 1.单一职责原则 单一职责原则(Single ...

  3. 学习设计模式 - 六大基本原则之单一职责原则

    设计模式总共有六大基本原则,统称为SOLID (稳定)原则,分别是S-单一职责原则(Single Responsibility Principle), O-开闭原则(Open closed Princ ...

  4. 学习设计模式 - 六大基本原则之接口隔离原则

    设计模式总共有六大基本原则,统称为SOLID (稳定)原则,分别是S-单一职责原则(Single Responsibility Principle), O-开闭原则(Open closed Princ ...

  5. 面向对象六大原则详解

    本文来说下面向对象六大原则 文章目录 概述 单一职责原则 里氏替换原则 依赖倒置原则 接口隔离原则 迪米特法则 开闭原则 六大原则总结 概述 这是设计模式系列开篇的第一篇文章.也是我学习设计模式过程中 ...

  6. 【设计模式】第一章 面向对象六大原则

    第一章 面向对象六大原则 文章目录 第一章 面向对象六大原则 一.指导思想 二.面向对象六大原则 1.单一职责原则 2.开闭原则 3.里氏替换原则 4.依赖倒置原则 5.接口隔离原则 6.迪米特法则 ...

  7. python设计模式六大原则_学习设计模式 - 六大基本原则之迪米特法则(示例代码)...

    设计模式总共有六大基本原则,统称为SOLID (稳定)原则,分别是S-单一职责原则(Single Responsibility Principle), O-开闭原则(Open closed Princ ...

  8. Java基础学习总结(84)——Java面向对象六大原则和设计模式

    面向对象六大原则 在此之前,有一点需要大家知道,熟悉这些原则并不是说你写出的程序就一定灵活.清晰,只是为你优秀的代码之路铺上了一层栅栏,在这些原则的指导下,你才能避免陷入一些常见的代码泥沼,从而让你写 ...

  9. java 面向对象原则_Java基础:面向对象六大原则

    本文主要介绍了面向对象六大原则. 单一职责原则(Single-Resposibility Principle). "对一个类而言,应该仅有一个引起它变化的原因."本原则是我们非常熟 ...

最新文章

  1. 收藏 | 2019 NLP大全:论文、博客、教程、工程进展全梳理(附链接)
  2. leetcode算法题--买卖股票的最佳时机含手续费
  3. Mybatis二级缓存原理
  4. HD_I Hate It
  5. js实现获取当前周,过去和未来周的时间段日期
  6. 是什么门的缩写_干货分享:汽车排气系统部件有什么?出故障都有什么现象?...
  7. UIAlterController-ios8弹出菜单
  8. swagger2 配置访问路径_有了Swagger2 再也不用担心API文档的维护了
  9. 关于mac m1 安装安卓模拟器
  10. 计算bed区间gc含量,碱基深度等
  11. Linux gerp 命令使用方法
  12. 创建 GitHub 个人访问令牌
  13. 【测试】详解接口测试(2)- HTTP接口用例设计与测试方法(拿B站练手)
  14. python处理期货数据_用python中的Pandas库实现一个商品期货网格策略
  15. 京东客服岗位人才考试
  16. logstash读取kafka所有topics 自动创建es 索引
  17. iOS及Mac开源项目和学习资料
  18. JS—随机三个0-9不重复的随机数
  19. Java生鲜电商平台-技术方案与文档下载
  20. 【LaTeX 教程】01. LaTeX 简介与安装

热门文章

  1. 【已解决】WPS2018 从第三页开始插入页眉页码(即前两页不要页眉页码)
  2. 计算机评分 游戏图形,win7系统评分中图形和游戏图形这两项有什么不同?
  3. 基于Ubuntu和STM32分析全局变量、局部变量、堆、栈
  4. JavaScript面试题集锦
  5. 【Android底层学习总结】2. 安卓系统内核的Bring Up
  6. ajax基础知识必看篇(黄梦岚)
  7. xtrabackup备份恢复
  8. ipad手写笔什么牌子好?最好用的电容笔
  9. PLC 西门子smart200 锁机 有图片证明分期付款 动态验证码
  10. mysql 5.6 全文索引_MySql5.6全文索引 及 5.7 中文索引插件ngram