设为首页 加入收藏

TOP

面向对象设计的SOLID原则(一)
2019-09-17 17:36:12 】 浏览:42
Tags:面向 对象 设计 SOLID 原则

S.O.L.I.D是面向对象设计和编程(OOD&OOP)中几个重要编码原则的首字母缩写。这几条原则是非常基础而且重要的面向对象设计原则。正是由于这些原则的基础性,理解、融汇贯通这些原则需要不少的经验和知识的积累。

SRP : 单一责任原则

        当需要修改某个类的时候原因有且只有一个。换句话说就是让一个类只做一种类型责任,当这个类需要承当其他类型的责任的时候,就需要分解这个类。

        通常一个类被修改的几率很大,因此我们应该专注单一功能。假如我们把很多功能放在一个类中,功能之间就形成了关联,我们修改其中一个功能便有可能中止另一个功能,这时我们就需要测试来避免可能出现的问题,浪费了很多时间。一个好的设计是把不同的职责分离出来,放进不同的类中,这样改变任意一个不会影响到其他的应用程序。

OCP: 开放封闭原则

        软件实体应该是可扩展,而不可修改的。也就是说,对扩展开放,对修改关闭。这是另一种非常棒的设计原则,可以防止其他人更改已经测试好的代码。理论上,可以在不修改原有的模块的基础上,扩展功能。这也是开闭原则的宗旨。这个原则是诸多面向对象编程原则中最抽象、最难理解的一个。

        1、通过增加代码来扩展功能,而不是修改已经存在的代码。

        2、如果客户模块和服务模块遵循同一个接口来设计,那么客户模块可以不关心服务模块的类型,服务模块可以方便扩展服务(代码)。

        3、OCP支持替换的服务,而不用修改客户模块。

        例如:我们现在有两种发送信息的方式,现在我们要增加一中方式。我们将需要在原来的方法中新增一个方法,在修改调用它的地方,这并不符合OCP原则。我们可以抽象出一个发送的接口,里面有发送的方法,然后我们让之前的两种发送方法去实现它,这样一来我们不管增加几种发送发式,只需要添加它的实现类和实现接口就可以了。不用再修改已有的接口和实现类,很好的遵循了OCP原则。在项目中应用OCP原则可以限制代码的更改,一旦代码完成,测试和调试之后就很少再去更改。这减少了给现有代码引入新bug的风险,增强软件的灵活性。

LSP : 里氏替换原则

        当一个子类的实例应该能够替换任何其超类的实例时,它们之间才具有is-A关系。

          换句话来说就是子类型能够完全替换父类型,而不会让调用父类型的客户程序从行为上有任何改变。因此,所有的子类必须按照和他们父类相同方式操作。子类的特定功能可能不同,但是必须符合父类的预期行为。一般来说,如果父类型的一个子类型做了一些父类型的客户没有预期的事情,那这就违反LSP。

          LSP经典案例是矩形和正方形的案例,正方形是要求长等于宽,如果你应该使用矩形的时候你却使用了正方形,不可预期的错误会发生,因为正方形的尺寸是不能被修改 (修改了就不是正方形,违背事物内在逻辑一致性)。

         我们回到面向对象的基本概念上,子类继承父类表达的是一种IS-A关系,IS-A关系这种用法被认为是面向对象分析(OOA)基本技术之一。

       《Java与模式》一书中的解释是:我们设计继承体系时,子类应该是可替代的父类的,是可替代关系,而不仅仅是IS-A的关系。

       而PPP一书中的解释是:从行为方式的角度来看,正方形不是长方形,对象的行为方式才是软件真正所关注的问题 ,LSP清楚地指出,OOD(面向对象设计)中IS-A关系时就行为方式而言的,客户程序是可以对行为方式进行合理假设的。

       其实二者表达的是同一个意思。

ISP : 接口分离原则

        不能强迫用户去依赖那些他们不使用的接口。换句话说,使用多个专门的接口比使用单一的总接口总要好。

        当你应用ISP时,类和他们的依赖使用紧密集中的接口通信,最大限度地减少了对未使用成员的依赖,并相应地降低耦合度。小接口更容易实现,提升了灵活性和重用的可能性。由于很少的类共享这些接口,为响应接口的变化而需要变化的类数量降低,增加了鲁棒性。

        不要依赖你不需要的东西:

        示例1:一个动物的行为接口中包含了“吃”、“爬”和“跑”,但蛇是不会跑的,所以有些是不必须的方法,更好的方法是我们将“爬”和“跑”单独做一个接口。这个要根据实际情况做调整,如果不是每个继承该接口的类都需要,就不能将所有的功能都放在同一个接口里。

        示例2:一个提款机有很多不同的操作,我们在取钱(拿走)的时候没服务费,在取钱(转账)的时候要扣服务费,我们能在取钱(拿走)的时候,提示取款扣服务费吗?       

        为什么要ISP(接口分离原则):

        否则 - 增加了不同客户端之间的耦合

        每个客户端对SRP基本上是一个变量

DIP: 依赖倒置原则

        1. 高层模块不应该依赖于低层模块,二者都应该依赖于抽象 
        2. 抽象不应该依赖于细节,细节应该依赖于抽象

        DIP是定位在高层次模块不应该依赖低层次模块,它们应该

首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇springmvc4整合mybatis框架源码 b.. 下一篇高并发下海量容器案例一

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目