面向对象的七大设计原则

总脉络图:

一:单一职责原则(全称:“Single-Responsibility Principle”)又称 单一功能原则

核心:解耦和增强内聚性(高内聚,低耦合)

说明:

就一个类而言,应该只专注于做一件事和仅有一个引起它变化的原因。所谓职责,我们可以理解他为功能,就是设计的这个类功能应该只有一个,而不是两个或更多。也可以理解为引用变化的原因,当你发现有两个变化会要求我们修改这个类,那么你就要考虑撤分这个类了。因为职责是变化的一个轴线,当需求变化时,该变化会反映类的职责的变化。

使用SRP注意点:

1、一个合理的类,应该仅有一个引起它变化的原因,即单一职责;

2、在没有变化征兆的情况下应用SRP或其他原则是不明智的;

3、在需求实际发生变化时就应该应用SRP等原则来重构代码;

4、使用测试驱动开发会迫使我们在设计出现臭味之前分离不合理代码;

5、如果测试不能迫使职责分离,僵化性和脆弱性的臭味会变得很强烈,那就应该用Facade或Proxy模式对代码重构;SRP优点:消除耦合,减小因需求变化引起代码僵化。

 

二、依赖倒转原则(全称:“Dependence Inversion Principle”)又称 依赖倒置原则或依赖反转原则

核心:要依赖于抽象,不要依赖于具体的实现

优点:使用传统过程化程序设计所创建的依赖关系,策略依赖于细节,这是糟糕的,因为策略受到细节改变的影响。依赖倒置原则使细节和策略都依赖于抽象,抽象的稳定性决定了系统的稳定性。

怎样做到依赖倒置?

以抽象方式耦合是依赖倒转原则的关键。抽象耦合关系总要涉及具体类从抽象类继承,并且需要保证在任何引用到基类的地方都可以改换成其子类,因此,里氏代换原则是依赖倒转原则的基础。

在抽象层次上的耦合虽然有灵活性,但也带来了额外的复杂性,如果一个具体类发生变化的可能性非常小,那么抽象耦合能发挥的好处便十分有限,这时可以用具体耦合反而会更好。

层次化:所有结构良好的面向对象构架都具有清晰的层次定义,每个层次通过一个定义良好的、受控的接口向外提供一组内聚的服务。

依赖于抽象:

建议不依赖于具体类,即程序中所有的依赖关系都应该终止于抽象类或者接口。

尽量做到:

1、任何变量都不应该持有一个指向具体类的指针或者引用。

2、任何类都不应该从具体类派生。

3、任何方法都不应该覆写它的任何基类中的已经实现的方法。

 

三:接口隔离原则(全称:“Interface Segregation Principle”)

 

核心思想:

 

不应该强迫客户程序依赖他们不需要使用的方法。

 

接口分离原则的意思就是:一个接口不需要提供太多的行为,一个接口应该只提供一种对外的功能,不应该把所有的操作都封装到一个接口当中.

 

分离接口的两种实现方法:

 

1.使用委托分离接口。(Separation through Delegation)

 

2.使用多重继承分离接口。(Separation through Multiple Inheritance)

 

四:迪米特原则(全称:“Law of Demeter”) 又称 最少知识原则

说明:

对象与对象之间应该使用尽可能少的方法来关联,避免千丝万缕的关系。

如何实现迪米特法则?

迪米特法则的主要用意是控制信息的过载,在将其运用到系统设计中应注意以下几点:

1) 在类的划分上,应当创建有弱耦合的类。类之间的耦合越弱,就越有利于复用。

2) 在类的结构设计上,每一个类都应当尽量降低成员的访问权限。一个类不应当public自己的属性,而应当提供取值和赋值的方法让外界间接访问自己的属性。

3) 在类的设计上,只要有可能,一个类应当设计成不变类。

4) 在对其它对象的引用上,一个类对其它对象的引用应该降到最低。

 

五:开闭原则(全称:“Open-Closed Principle”)

 

核心思想:对扩展开放,对修改关闭。

 

优点:

按照OCP原则设计出来的系统,降低了程序各部分之间的耦合性,其适应性、灵活性、稳定性都比较好。当已有软件系统需要增加新的功能时,不需要对作为系统基础的抽象层进行修改,只需要在原有基础上附加新的模块就能实现所需要添加的功能。增加的新模块对原有的模块完全没有影响或影响很小,这样就无须为原有模块进行重新测试。

 

如何实现“开-闭”原则?

 

在面向对象设计中,不允许更改的是系统的抽象层,而允许扩展的是系统的实现层。换言之,定义一个一劳永逸的抽象设计层,允许尽可能多的行为在实现层被实现。

 

解决问题关键在于抽象化,抽象化是面向对象设计的第一个核心本质。

 

对一个事物抽象化,实质上是在概括归纳总结它的本质。抽象让我们抓住最最重要的东西,从更高一层去思考。这降低了思考的复杂度,我们不用同时考虑那么多的东西。换言之,我们封装了事物的本质,看不到任何细节。

 

在面向对象编程中,通过抽象类及接口,规定了具体类的特征作为抽象层,相对稳定,不需更改,从而满足“对修改关闭”;而从抽象类导出的具体类可以改变系统的行为,从而满足“对扩展开放”。

 

对实体进行扩展时,不必改动软件的源代码或者二进制代码。关键在于抽象。

 

六:合成复用原则(全称:Composite Reuse Principle,CRP)

 

核心思想:

 

尽量使用对象组合,而不是继承来达到复用的目的。该原则就是在一个新的对象里面使用一些已有的对象,

 

使之成为新对象的一部分:新的对象通过向这些对象的委派达到复用已有功能的目的。

 

复用的种类:

 

1.继承

 

2.合成聚合

 

注:在复用时应优先考虑使用合成聚合而不是继承

只有当以下的条件全部被满足时,才应当使用继承关系。

         1. 子类是超类的一个特殊种类,而不是超类的一个角色,也就是区分“Has-A”和“Is-A”.只有“Is-A”关系才符合继承关系,“Has-A”关系应当使用聚合来描述。

         2 .永远不会出现需要将子类换成另外一个类的子类的情况。如果不能肯定将来是否会变成另外一个子类的话,就不要使用继承。

         3 .子类具有扩展超类的责任,而不是具有置换掉或注销掉超类的责任。如果一个子类需要大量的置换掉超类的行为,那么这个类就不应该是这个超类的子类。

         错误的使用继承而不是合成/聚合的一个常见原因是错误地把“Has-A”当成了“Is-A”.”Is-A”代表一个类是另外一个类的一种;而“Has-A”代表一个类是另外一个类的一个角色,而不是另外一个类的特殊种类。

 

七:里氏替换原则(全称:“Liskov Substitution Principle”)

核心:

1.在任何父类出现的地方都可以用他的子类来替代(子类应当可以替换父类并出现在父类能够出现的任何地方)

子类必须完全实现父类的方法。在类中调用其他类是务必要使用父类或接

口,如果不能使用父类或接口,则说明类的设计已经违背了LSP原则。

2.子类可以有自己的个性。子类当然可以有自己的行为和外观了,也就是方法和属性

3.覆盖或实现父类的方法时输入参数可以被放大。即子类可以重载父类的方法,但输入参数应比父类方法中的大,这样在子类代替父类的时候,调用的仍然是父类的方法。即以子类中方法的前置条件必须与超类中被覆盖的方法的前置条件相同或者更宽松。

4.覆盖或实现父类的方法时输出结果可以被缩小。

 

 

 

 

转载于:https://www.cnblogs.com/WJ-163/p/5382182.html

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

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

相关文章

人机融合智能的思考

来源:人机与认知实验室【人机智能难于融合的主要原因就在于时空和认知的不一致性,人处理的信息与知识能够变异,其表征的一个事物、事实既是本身同时又是其他事物、事实,一直具有相对性,机器处理的数据标识缺乏这种相对…

工艺篇:常用表面处理

工艺篇:常用表面处理 表面处理定义 表面处理是在基体材料表面上人工形成一层与基体的机械、物理和化学性能不同的表层的工艺方法。表面处理的目的是满足产品的耐蚀性、耐磨性、装饰或其他特种功能要求,表面处理按照机理来分可以分为以下4部分&#xff…

NASA发现超级地球,真的适宜居住?

来源:中国新闻网中新网8月2日电 当地时间7月31日,NASA宣布,他们的凌日系外行星勘测卫星(TESS),在距离地球约31光年的地方,发现了一颗可能有生命存在的“超级地球”。天文学家制作的GJ357d星球概念图。图片来源&#xf…

Excel制作随机抽取名单

首先建立名单,假设放在A列 然后选一个方格用来存抽取结果,并在该方格中输入INDEX(A:A,RANDBETWEEN(1,8)),1:8表示第1行到第8行 此时按下F9键就可以生成随机的名单了 增加抽取效果: 首先选取全部名单: 点击条件格式→…

RuntimeError: CUDA out of memory. Tried to allocate 132.00 MiB (GPU 2; 3.95 GiB total capacity; 3.41

pytorch报错:RuntimeError: CUDA out of memory. Tried to allocate 132.00 MiB (GPU 2; 3.95 GiB total capacity; 3.41 GiB already allocated; 37.88 MiB free; 98.29 MiB cached) 如果是训练时遇到该问题,说明模型的参数太多了,将模型的…

31个惊艳的数据可视化作品,让你感受“数据之美”!

来源:中国智慧城市导刊在一个信息大爆炸的时代,每天都有很多的新消息、新发现、新趋势向我们狂轰乱炸而来。在这个过程中,我们既是数据的生产者,也是数据的使用者,然而初次获取和存储的原始数据总是杂乱无章的。要想数…

BBC分析了365个职业,发现最不可能被机器淘汰的居然是……

来源:中国智慧城市导刊记得钱塘江大潮期间,有段视频在网上走红:观潮的人群拥挤在钱塘江边,争看远处潮水滚滚而来,当人们前一秒还在沉浸在拍照嬉闹中,下一秒滔天巨浪已拍上岸边,避之不及的围观人…

工艺篇:表面粗糙度

表面粗糙度 表面粗糙度(surface roughness)是指加工表面具有的较小间距和微小峰谷的不平度 。其两波峰或两波谷之间的距离(波距)很小(在1mm以下),它属于微观几何形状误差。表面粗糙度越小,则表面越光滑。 …

从Nature 封面文章“天机”芯片看脑科学与AI的融合

来源:混沌巡洋舰7月31日Nature杂志封面刊登了清华类脑计算团队的最新成果:天机芯片以及由其操控的自行车。Towards artificial general intelligence with hybrid Tianjic chip architecture这则信息在一天之内在AI圈子引起了热议,而大部分吃…

[BZOJ4530][Bjoi2014]大融合 LCT + 启发式合并

[BZOJ4530][Bjoi2014]大融合 试题描述 小强要在N个孤立的星球上建立起一套通信系统。这套通信系统就是连接N个点的一个树。这个树的边是一条一条添加上去的。在某个时刻,一条边的负载就是它所在的当前能够联通的树上路过它的简单路径的数量。例如,在上图…

器件篇:步进电机

器件篇:步进电机 步进电机是将电脉冲信号转变为角位移或线位移的开环控制元步进电机件。在非超载的情况下,电机的转速、停止的位置只取决于脉冲信号的频率和脉冲数,而不受负载变化的影响,当步进驱动器接收到一个脉冲信号&#xf…

pytorch中的参数初始化方法

参数初始化(Weight Initialization) PyTorch 中参数的默认初始化在各个层的 reset_parameters() 方法中。例如:nn.Linear 和 nn.Conv2D,都是在 [-limit, limit] 之间的均匀分布(Uniform distribution)&…

物理学走到尽头了吗?

图片来源:pixabay.com来源: 蔻享学术我的英雄理查德费曼(Richard Feynman)曾开玩笑地说:“爱因斯坦是个巨人。他的头虽然在云里,脚却踩在地上。而我们这些个子不高的人则必须做出一个选择!”可我…

QT示例:基于TCP点对点Socket通讯

QT示例:基于TCP点对点通讯一、 概述二、TCP 协议工作原理三、TCP 编程模型四、基于TCP点对点通讯示例1、客户端2、客户端Client示例3、服务器4、服务器server示例下载:基于TCP点对点通讯 一、 概述 二、TCP 协议工作原理 三、TCP 编程模型 四、基于TCP点…

50 年人类登月史:那些不为人知的故事

来源: CSDN2019年7月20日是纪念人类登月五十周年的好日子。人类于1969年首次正式登上月球,历史将永远铭记两位宇航员的名字:尼尔阿姆斯特朗与巴兹奥尔德林。 然后,这背后还有很多不为人知的故事。 在我们庆祝首次登月成功的同时&a…

物理学走到尽头了吗 | 维尔切克专栏

来源:环球科学撰文 | 弗兰克维尔切克(Frank Wilczek)翻译 | 胡风 梁丁当“物理学家沉迷于追求数学的优美,却正在丧失解决新问题的能力。” “顶级的物理学家不再关心物理现实——当然他们也不用关心这些。” “科学完了。”这几句…

C# “配置系统未能初始化” 异常解决

使用App.config配置参数,读取参数出现错误 “System.Configuration.ConfigurationErrorsException”类型的未经处理的异常在 System.Configuration.dll 中发生 其他信息: 配置系统未能初始化 验证App.config文件没有结构错误 解决办法: 如果配置文件中包…

从零到无穷——美国数学的崛起之路

来源:今日头条从十七世纪开始,大批各种各样的欧洲移民开始涌入北美新大陆,也是从这个时候开始,科技革命的号角在欧洲开始吹响。但在相当长的一段时间内,北美大陆的居民仍在为生存而挣扎,像数学这样的科学在…

IAR STM32报错Error[Pe147]:declaration is incompatible with“__nounwind __interwork __softfp unsigned

IAR STM32工程中报错: Error[Pe147]: declaration is incompatible with "__nounwind __interwork __softfp unsigned int __iar_builtin_REV16(unsigned int)" (declared at line 197 of "D:\STM32F103_Demo\Core\core_cm3.h 解决方法&#xff1…

JAVA设计模式之工厂模式

在面向对象编程中, 最通常的方法是一个new操作符产生一个对象实例,new操作符就是用来构造对象实例的。但是在一些情况下,new操作符直接生成对象会带来一些问题。举例来说,许多类型对象的创造需要一系列的步骤:你可能需…