设计模式6大原则简述

0、前言

  这一段时间一直在看设计模式,里面分多次提到几个设计原则,看了几次发现记不清楚,还是得自己动手总结一下吧,把书上的理论先理解写下来再说喽。

1、单一职责原则

  • 定义:不要存在多于一个导致类变更的原因,通俗的说就是一个类只负责一项职责。
  • 优点
    • 降低类的复杂度,一个类只负责一个职责,其逻辑一定会比一个类负责多项职责要简单,同时也易于维护
    • 提高类的可读性,提高系统的可维护性
    • 降低变更所带来的风险;系统的变更是必然的,如果单一职责原则遵守的好,那么当修改一个功能时可以显著降低对其他功能的影响

  虽说我们要遵守单一职责原则,但是也不是说死板的对每一个细节都严格遵守,也要视情况而定:如果一个类的逻辑非常简单且可以保证变化极小,此时可以在代码级别上违反单一职责原则;另外当一个类中方法很少时,也可以在方法的级别上违反这一原则。(这里我这么理解单一职责原则:分为两个层次,最高层次是类的层次,其次是方法层次上)但是如果一个类相对庞大,类中方法较多时,一定要遵守单一职责原则;宁愿在第一次扩展时花费精力完成重构,也要遵守这一原则,否则会给以后的扩展带来不可预估的灾难!

2、里式替换原则

  • 定义
    • 如果对每一个类型为T1的对象o1,都有类型为T2的对象o2,使得以T1定义的所有程序P在所有的对象o1都替换为o2时,程序P的行为没有发生变化;那么类型T2是类型T1的子类型
    • 所有引用基类的地方必须可以透明的使用其子类的对象
    • 通俗的讲就是:一个软件实体如果使用的是一个父类的话,那么一定适用于其子类,而且它察觉不出父类对象和子类对象的区别。也即在软件里面把父类都替换成他的子类,程序的行为没有发生任何变化。

  继承包含这样一层含义:父类中凡是已经实现好的方法(区别于抽象方法),实际上是在设定一系列的规则和契约,虽然它并不要求所有的子类都必须强制遵守这些规则,但是如果子类任意对这些非抽象方法进行重写,就会对整个继承体系造成破坏。里式替换原则主要就是想表达这一层含义。

  当然如果你非要重写父类的非抽象方法,这时应该采用这样的方式:原来的父类和子类都继承自一个更通用的基类,原有的继承关系去掉,转而采用依赖、聚合、组合等关系来替代。

  里式替换原则更通俗的说就是:子类可以扩展父类的功能,但是不能修改父类原有的功能;具体有以下4中含义:

  • 子类可以实现父类的抽象方法,但是不能覆盖父类的非抽象方法
  • 子类可以增加自己特有的方法
  • 当子类的方法重载父类的方法时,方法的前置条件(形参)要比父类方法的输入方法更宽松
  • 当子类实现父类的抽象方法时,方法的后置条件(即方法返回值)要比父类更严格

  如果在开发中不遵循里式替换原则程序也照样跑的好好地,那么也没啥差别啊?这就错了,这样的后果就是你的代码出错的几率会大大的增加。

3、依赖倒转原则

  • 定义:抽象不应该依赖细节,细节应该依赖于抽象(说白了就是要针对接口编程,不要对实现编程);也即:
    • 高层模块不应该依赖于底层模块,二者都应该依赖于抽象;
    • 抽象不应该依赖于细节,细节应该依赖于抽象
  • 依赖倒转原则基于这样一个事实:相对于细节实现中的多变性,抽象的东西要稳定的多;以抽象为基础搭建起来的架构比以细节为基础搭建起来的架构要稳定的多。具体来说(.NET+C#),抽象一般指的是接口、抽象类,细节就是具体的实现类。使用抽象的目的是制定好规范和契约,而不要涉及具体的实现,把细节交给他们的实现类来完成。

  依赖倒转原则的核心就是面向接口编程,传递依赖关系有三种方式:接口传递、构造方法传递、setter传递(如果用过spring框架,那么对传递一定会很熟悉)。在实际的开发中我们主要通过以下几点来较好的遵守依赖倒转原则:

  • 底层模块尽量都要有抽象类或接口,或两者都有
  • 变量的声明类型尽量是抽象类或接口
  • 使用继承时要遵循里式替换原则

  遵循依赖倒转原则可以降低类之间的耦合性,提高系统稳定性,降低修改造成的风险。同时,采用依赖倒转原则给并行开发带来了极大的便利,参与开发的人越多、项目越庞大依赖倒转原则意义和好处就越明显。当前比较流行的TDD开发模式就是依赖倒置原则非常成功的应用。

4、迪米特法则

  • 定义(也叫最少知道原则)
    • 如果两个类不必直接通信,那么这两个类就不应当发生直接的相互作用。如果一个类需要调用另一个类的方法,可以通过第三方来转发这个调用
    • 一个对象应该保持对其他对象最少的了解

  通俗的来讲,就是一个类对自己以来的类知道的越少越好;也就是说对于被依赖的类来说,无论逻辑多么复杂,都应当把逻辑封装在内部,对外除了提供public方法之外,不泄露其他任何信息。再通俗来说:迪米特法则就是‘只与直接的朋友通信’。那么什么是直接的朋友呢:每个对象都会与其他对象有耦合关系,只要两个对象间出现耦合关系,我们就说两个对象之间是朋友关系。而耦合的方式有很多,依赖、关联、聚合、组合都是耦合关系;其中,我们称出现成员变量、方法参数、方法返回值中的类为直接朋友,而出现在局部变量中的类则是间接朋友关系。也就是说陌生的类最好不要作为局部变量的形式出现在类的内部。

  迪米特法则的初衷是降低类之间的耦合,但是凡事都有一个度,虽然可以避免与非直接类之间的通信,但是要通信就必须通过一个中介来发生关系;而过分的使用迪米特法则,就会产生大量这样的中介和传递类,导致系统的复杂度增加。所以在使用迪米特法则时,要反复权衡,既要做到结构清晰又要高内聚低耦合。

5、开放-封闭原则

  • 定义:一个软件实体(如类、模块、函数等)应该对扩展开放,对修改关闭;即可以扩展但是不能修改
  • 当软件需要变化时,尽量通过扩展软件实体的行为来实现变化,而不能通过修改已有代码来实现变化。

  开放-封闭原则是面向对象设计中最基础的原则,它指导我们如何建立稳定、灵活的系统。但是他也是这几个模式中定义最为模糊的一个,在初接触它时,总给你一种无处下手的感觉,因为它太虚了。但是当把其他原则还有23中设计模式通读了一遍之后,我发现可以这么理解它:开放-封闭原则是战略,而其他的几个原则以及设计模式就是具体的战术;如何实现开放-封闭原则呢?要想实现一个战略,就必须要制定合适的战术:即,通过较好的遵守其他几个原则以及通过合适的设计模式,最终实现一个软件很好的开发-封闭原则。

※其他【接口隔离原则】

  客户端不应该依赖它不需要的接口,一个类对另一个类的依赖应该建立在最小的接口上。

  可以这么理解:如果接口过于臃肿,那么实现他的类不管用不用的到,都必须实现接口中所有的方法,这显然是不好的设计;这时候就需要遵循接口隔离原则对臃肿的接口进行拆分。他的原则就是:尽量建立单一的接口,尽量细化接口,接口中的方法尽量少。也就是说,我们要为各个类建立专用的接口,而不是试图去建立一个很庞大的接口共所有依赖他的类去调用。

  这里接口隔离原则与单一职责原则也有一定的区别,主要从以下方面来看:

  • 单一职责原则注重的是职责,而接口隔离注重的是对接口依赖的隔离;
  • 单一职责原则主要约束的是类,其次才是接口和方法,它主要针对的是程序中实现的细节;而接口隔离原则主要针对接口和抽象,针对程序框架的构建。

  但是在使用接口隔离原则时也一定要适度,一定要注意:

  • 接口尽量小,但是也要有限度。如果接口过小,会造成接口过多,而导致增加设计的复杂度。
  • 为依赖接口的类定制服务,只暴露给调用他的类所需要的方法,他不需要的方法则要隐藏起来。只有专注的为一个模块提供定制服务,才能建立最小的依赖关系。

  最后的这个接口隔离原则,我的看法就是:只是从更加细小的粒度上解释了单一职责原则。因此在这里放在最后的其他里面描述他。同时,这几个原则现在只是对照着定义还是自己很少的开发经历来理解,很多还无法清楚的理解和使用,后面还有很长的路需要走啊,加油!

转载于:https://www.cnblogs.com/qingtian-jlj/p/6209157.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/417512.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

前端学习(2216):react元素渲染

index.js import React from react; import ReactDOM from react-dom; import ./index.css; import App from ./App;//<app/>js的普通对象 let app < App / >let root document.getElementById(root)let h1<h1>helloworld<span>我是</span>&l…

SQLServer LIKE 通配符

将通配符作为文字使用 可以将通配符模式匹配字符作为文字字符使用。若要将通配符作为文字字符使用&#xff0c;请将通配符放在方括号中。下表显示了几个使用 LIKE 关键字和 [ ] 通配符的示例。 符号含义 LIKE 5[%] 5% LIKE [_]n _n LIKE [a-cdf] a、b、c、d 或 f LIKE [-acdf] …

计算机应用基础专科作业二,电子科大18秋《计算机应用基础(专科)》在线作业2...

电子科大18秋《计算机应用基础(专科)》在线作业2谋学网http://doc.docsou.com【奥鹏】[电子科技大学]18秋《计算机应用基础(专科)》在线作业2试卷总分:100 得分:100第1题,在浏览网页中&#xff0c;下列可能泄露隐私的是()。A、HTML文件B、文本文件C、CookieD、应用程序第2题,IP…

苹果ipadwps_ipad可以用wps吗?

展开全部可以。Ipad由于采用ARM架构&#xff0c;62616964757a686964616fe59b9ee7ad9431333431346435不能兼容普通PC台式机和笔记本的程序&#xff0c;但可以通过安装由Apple提供的iWork套件进行办公&#xff0c;也可以通过iOS第三方软件预览和编辑Office和PDF文件。而WPS又可以…

【干货分享】前端面试知识点锦集03(JavaScript篇)——附答案

三、JavaScript部分 1、谈谈你对Ajax的理解&#xff1f;(概念、特点、作用) AJAX全称为“Asynchronous JavaScript And XML”&#xff08;异步JavaScript和XML&#xff09; 是指一种创建交互式网页应用的开发技术、改善用户体验&#xff0c;实现无刷新效果。 优点a、不需要插件…

前端学习(2219):react之jsx小案例

import React from react; import ReactDOM from react-dom; import ./index.css; import App from ./App; import { tsPropertySignature } from babel/types;//<app/>js的普通对象 /*let app < App / >let root document.getElementById(root)let h1<h1>…

IL编译反编译

运行VS命令提示反编译到ILildasm /source DemoCrack.exe /out:crack.il 编译il到exeilasm crack.il

spark 不同模式用途_Spark 的四种模式

1.spark主要有四种运行模式&#xff1a;Loca 、standalone、yarn、mesos。1)Local模式&#xff1a;在一台机器上&#xff0c;一般用于开发测试2)standalone模式&#xff1a;完全独立的spark集群&#xff0c;不依赖其他集群&#xff0c;分为Master和work。客户端向Master注册应用…

软件测试人员棘手的问题,软件测试的棘手问题:如何避免重复提交缺陷

对于测试工程师来说&#xff0c;无论是新手还是老手&#xff0c;测试久了&#xff0c;尤其是遇到一些复杂的项目&#xff0c;难免会犯重复提交缺陷的错误。那么问题来了&#xff0c;我们要怎样避免这类诟病呢&#xff1f;换句话说&#xff0c;怎样才能避免缺陷的重复提交&#…

前端学习(2220):react之jsx的样式小案例

import React from react; import ReactDOM from react-dom; import ./index.css; import ./App.css import App from ./App; import { tsPropertySignature } from babel/types;//<app/>js的普通对象 /*let app < App / >let root document.getElementById(root…

.Net DES加密解密(不带向量)

/// <summary>/// DES加密字符串/// </summary>/// <param name"encryptString">待加密的字符串</param>/// <param name"Key">密钥</param>/// <returns>加密成功返回加密后的字符串&#xff0c;失败返回源串&…

SyntaxError: Non-UTF-8 code starting with '\xba' in file 错误的解决方法!!

第一次在Eclipse建立python工程&#xff0c;添加了自己新建的文件&#xff0c;写了一点代码&#xff0c;随后执行时候出现了错误&#xff0c;和昨天我在Visual Studio 2015里面一样&#xff0c;错误&#xff1a; SyntaxError: Non-UTF-8 code starting with \xba in file G:\wo…

开机预读快还是不预读快_WIN 7下的超级预读比VISTA要好,改进不少!推荐开启超级预读!...

预读技术是微软vista和windows7默认开启的程序&#xff0c;原意是增加程序运行和开机速度&#xff0c;但事与愿违&#xff0c;该技术已经变成与UAC几乎一样的垃圾&#xff0c;普通用户建议关闭&#xff0c;原因有&#xff1a;1、程序本身额外增加系统负担&#xff0c;启用就多运…

朋友圈计算机代码,微信小程序仿朋友圈代码

【实例简介】微信小程序实现朋友圈页面。UGC发布&#xff0c;包含获取用户授权信息。【实例截图】【核心代码】circle├── circle│ ├── app.js│ ├── app.json│ ├── app.wxss│ ├── components│ │ └── list│ │ ├── list.js│ │ …

如何在excel不同的工作表之间使用数据有效性?

选择“数据有效性”之后&#xff0c;在“允许”里从下拉列表里选择“列表” 在“源”中输入“INDIRECT("表名!$列名$行名:$列名$行名")如I列的3到7行:INDIRECT("Sheet2!$I$3:$I$7")或INDIRECT("Sheet2!I3:I7") 指定一列 INDIRECT("Sheet2!$…

三维向量变化为角度_物体的三维识别与6D位姿估计:PPF系列论文介绍(四)

作者&#xff1a;仲夏夜之星Date&#xff1a;2020-04-14来源&#xff1a;物体的三维识别与6D位姿估计&#xff1a;PPF系列论文介绍(四)文章“3D Pose Estimation of Daily ObjectsUsing an RGB-D Camera”2012发表在IEEE/RSJInternational Conference on Intelligent Robots an…

视频转换工具(命令行)

转换视频到flvE:\TDDOWNLOAD\ffmpeg-git-1929807-win32-static\bin\ffmpeg.exe -i e:\1.avi -ab 56 -ar 22050 -b 500 -r 15 -s 480x360 e:\1.flv转换支持的格式ffmpeg.exe -formats 播放视频ffplay.exe e:\1.flv

计算机win10启动慢,Win10 开机慢/Win10启动慢的常见原因

吴川华南区技术负责人概要很多用户反馈电脑经过使用一段时间后&#xff0c;在开机或运行的时候变得十分缓慢。本文将针对Win 10启动慢(Win 10开机慢)这一问题&#xff0c;来为大家分析其原因及解决方案。新买的电脑一般都运行顺畅&#xff0c;不过使用一段时间后&#xff0c;在…

普通筛法时间界的证明

普通筛法时间界 O(nlnlnn) 的证明 定义 朴素素数筛法即是利用每一个素数筛出所有他的倍数。 证明 对于待筛选的最大数n&#xff0c;由于素数分布定理&#xff0c;其中的素数个数约等于 nlnn&#xff0c;第i个素数约为 ilni。则算法总的运行次数为&#xff1a; ∑i1nlnnnilnin∑…