面向对象6大原则

2019-11-14  本文已影响0人  Johnson_Coding

1.单一职责原则 比如说一个ImageLoader,需要加载图片和缓存图片,此时如果将这两个功能都放在一个类中,就违反了这个原则,我们需要将不同的功能用类精细组织起来,然后通过成员变量的形式将功能组合起来。
2.开闭原则 如果我们要在1的基础上增加更多的硬件缓存或者双缓存,此时如果只是在原来的类中使用if进行判断那么就违反了这个原则,因为对于一个类我们需要的是对于修改是关闭的,对于扩展是开发的,此时我们就可以将缓存类定义成抽象的接口,然后将各个缓存的实现,以多态的形式设置在ImageLoader之中,此时我们只需要为ImageLoader设置一个具体ImageCache实现类,而不需要对ImageLoader进行修改。
3.里氏替换原则 在2的基础上,接口的实现需要符合这个原则,这个原则是基于继承和多态这两个性质,而这个原则就是:如果将接口的实现或者基类的子类设置进入ImageLoader之中,不会出现任何问题。
4.依赖倒置原则 模块之间的依赖关系通过抽象发送,实现类之间不发生直接的依赖关系,依赖关系是通过接口或者抽象产生的。
5.接口隔离原则 类之间的依赖关系应该建立在最小的接口之上,如果一个接口非常臃肿那么需要将这个接口细分。
6.最少知识原则 一个类应该对自己需要耦合或调用的类知道的越少越好,因为一个类对另一个类了解的越多,在重构的时候另一个类需要改的就越多。

一、 单一职责原则

Single Responsibility Principle(SRP),对于一个类,应该只有一个引起它变化的原因。
以图片加载类(ImageLoader)为例:


image.png

一开始设计的类内:初始图片缓存;展示图片;下载图片三大功能
剔除缓存功能后,设计为两个独立类,区分彼此的作用。

二、 开闭原则

Open Close Principle(OCP),软件中的对象(类、模块、函数等)应对于拓展开放,对于修改封闭。实际开发中比较难做到~~~


image.png

改造之前的设计:
讲图片缓存类设计为接口:get和put用于实现
好处:实现了接口后自行实现get、put逻辑不会对ImageLoader造成修改;
用户可以自定义缓存通过实现方法自行实现缓存策略;
拥有良好的拓展性。

三、 里式替换原则

Liskov Substitution Principle(LSP),所有引用基类的地方必须能透明的使用其子类对象。


image.png

上述代码示例所示,Window依赖于View,View是抽象的具体实现由子类决定。任何继承自View的子类都可以设置给Window的show方法,就是所说的里式替换。
由上我们可以看出——抽象——是走向代码优化的重要一步。

四、 依赖倒置原则

Dependence Inversion Principle(DIP),高层次的代码不依赖于低层次的模块的实现细节的目的。
(1) 高层模块不应该依赖底层模块,两者都应依赖其抽象;
(2) 抽象不应该依赖于细节;
(3) 细节应该依赖于抽象。
用上面的ImageLoader可以说明:将ImageCache抽象为接口,而不是具体的MemoryCache或者是DiskCache,这样ImageLoader就依赖于抽象的ImageCache而不是具体细节,用户只需要实现ImageCache类或者是用其他已继承ImageCache的类完成对应的缓存功能,然后将具体的实现注入到ImageLoader中实现缓存功能的替换,保证了缓存的高扩展性,有了拥抱变化的能力,这就是依赖导致原则。

五、 接口隔离原则

InterfaceSegregation Principle(ISP),类间的依赖关系应该建立在最小的接口上。
例如:Java和Android里经常会使用到输入输出流/Cursor之类的可关闭对象(实现了Closeable功能),而每次写诸如这样的代码时都会有冗长的trycatchfinally操作,易读性极差,但是Java提供了Closeable接口,因此我们做简单的封装就可以简化我们的代码:


image.png

这样一来每次用到需要关闭的对象时,使用上面的代码就能提高代码的可读性。
基本原理就是依赖于Closeable抽象而不是具体实现,并建立在最小化依赖原则的基础上,它只要知道这个对象是可关闭的其他一律不管,这就是这里的接口隔离原则。

上一篇 下一篇

猜你喜欢

热点阅读