面向对象的SOLID五大原则( 二 )


面向对象的SOLID五大原则

文章插图
 
还是那句话任何基类可以出现的地方,子类一定可以出现,所以在创建Rectangle对象指针的时候,这里其实给的是子类的对象,最终代码运行断言报错 。
Assertion failed: rect->GetArea() == 10, file .main.cpp, line 10如果new出来的对象是Rectangle,则程序能够正常执行 。如果new出来的是Square则会进入断言 。从而Square不能代替Rectangle,所以不符合LSP原则,实际上Square并不是Rectangle的子类 。
正方形是长方形,但是他们的行为并不一样,所谓的行为,就是抽象出来的东西 。正方形只要有一个设置边长的方法就行了,而长方形需要设置宽和高两种方法 。
4. ISPISP(ISP-Interface Segregation Principle)接口隔离原则 。
ISP定义:
不应强制客户端依赖于它们不使用的接口(Clients should not be forced to depend upon interfaces that they do not use.)
该原则还有另外一个定义:一个类对另一个类的依赖应该建立在最小的接口上(The dependency of one class to another one should depend on the smallest possible interface)
假如现在有一个OPS类 。用户1只需要使用OPS类的op1方法,用户2只需要OPS类的op2方法,但是呢,OPS类除了提供op1和op2方法还提供了若干方法 。如下图:
面向对象的SOLID五大原则

文章插图
 
此时用户2没什么意见,心想着反正能实现我要的功能就可以了 。
但是呢,用户1不愿意,于是就去找开发人员理论,我就要实现一个op1功能,给我整这么多依赖干啥 。除了这个功能,其他的全部都给我隐藏掉,下班之前我就要,说完头一扭就走了 。
开发人员心想,这么简单的事情,让我下班之前给你,这不是狗眼看人低吗,说完就在用户1和OPS之间又封装一层IU1Ops接口,两分钟搞定 。于是就去跟用户1说,你用IU1Ops,里面有你要的接口,拿去用吧 。说完头一扭就走了 。模型如下图:
面向对象的SOLID五大原则

文章插图
 
接口隔离原则和单一职责都是为了提高类的内聚性、降低它们之间的耦合性,体现了封装的思想,但两者是不同的:
  • 单一职责原则注重的是职责,而接口隔离原则注重的是对接口依赖的隔离 。
  • 单一职责原则主要是约束类,它针对的是程序中的实现和细节;接口隔离原则主要约束接口,主要针对抽象和程序整体框架的构建 。
5. DIPDIP(DIP-Dependency Inversion Principle)依赖倒置原则 。
DIP定义:
高层次的模块不应该依赖低层次的模块,他们都应该依赖于抽象(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)
这个名字看着有点别扭,“依赖”还“倒置”,这到底是啥意思?
依赖指两个相对独立的对象,当一个对象负责构造另一个对象的实例,或者依赖另一个对象的服务时,这两个对象之间主要体现为依赖关系 。
老样子,看示例,现在甲方需要能让BMW车跑起来的功能,再看一下乙方的设计 。
面向对象的SOLID五大原则

文章插图
 
司机有驾驶BMW车辆的方法,BMW车辆有run的方法,所以是甲方满足需求的 。
后来甲方需求变了,甲方不仅要能开BMW车,也要能开Benz车,却发现使用乙方原来的的设计Benz车却开不起来,因为+driver()只接受BMW的车辆,不接受Benz的车辆,这明显不合理,一个司机会开BMW却不会开Benz,太反常了 。于是去找乙方重新设计 。
乙方也认识到了不足,经过多方讨论终于有了如下设计 。


推荐阅读