面向对象六大原则,到底在说什么?

Posted mo_weifeng

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了面向对象六大原则,到底在说什么?相关的知识,希望对你有一定的参考价值。

面向对象六大原则不一定需要死记硬背,只要知道为什么我们需要这六大原则就可以了。

开发中总是有各种各样的架构问题,而六大原则有助于我们完成高扩展性、低耦合、高内聚的目标。

单一职责

制定流程,分工合作。

所有功能都写在一个类,功能越来越多,类越来越大,代码越来越复杂,无法扩展,也不灵活,这是低级程序员的通病~

比如说MVC模式,一个Activitiy既负责处理View,又负责处理业务逻辑,Activity的代码越来越膨胀,就像一个炸弹,随时会爆炸。于是有了MVP,有Presenter去专门负责处理业务逻辑,分担Activitiy的重担。但Presenter和Activity互相持有,一不小心又会内存泄露,于是有了MVVM的LiveData专门去优化这个问题,将原先数据之间的流转,变成一个订阅/发送的观察者模式。

完全不一样的功能,就不应该放在一个类。一个类应该是相关性很高的函数、数据的封装。

如果企业的CEO全部事都自己干,那么他就会越来越忙,越来越容易出错。如果CEO将自己的事情分离出来,交给专人处理,自己只负责制定分工流程和管理下属即可。如果一件事换了一个人处理,CEO也只是改变了处理对象,分工流程并不需要改变。

举个例子,图片加载器,不能把显示、下载、处理缓存的功能都放一起。这几个功能是不同的职责,应该单独创建类,分别只做自己的事情。当这几个功能各自改动时,并不需要改动图片加载器。我们可以使用外观模式,把图片加载器变成SDK一样使用。图片加载器的配置,可以使用建造者模式。

如何划分一个类或者函数的职责,每个人都有自己的看法,根据个人经验和具体业务逻辑而定。

开闭原则

有新变化时,不应该打扰到旧事物。

代码必须具有高扩展性,当我们升级、维护时,改动原来已经经过测试的代码,会对原有系统造成不可预知的影响。我们应该学会扩展代码,尽量少影响原有模块。

比如企业进行业务调整时,吩咐员工将已有的功能进行大改,出现流程问题时进行不下去时,又要调整其它的老业务,导致bug连连出现,怎么办?建立一只新业务团队负责研发新业务,替代部分老业务,如果不合适,能随时切换回老业务。

举个例子,图片加载器,如果把内存缓存、本地缓存、双缓存都写在图片加载器了,要再增加一个新的缓存处理方式,岂不是要改动图片加载器?我们需要把处理方法抽象出来做成接口,具体类去实现接口。图片加载器只依赖接口,并不需要关心具体实现。这样一旦有了新的缓存处理方式,图片加载器也不用改动,只要改变传入的对象即可。这就是典型的策略模式。

比如说装饰模式,我想给老功能加点新逻辑,那么我可以给老功使用装饰者给他功能增强一下,就变成了一个新的功能了。

里氏替换

利用抽象,可千变万化。

无聊是TextView,还是ImageView,其实都是继承View。View是一个抽象类,它把测量和绘制的行为都抽象出来。继承View的类可随意发挥,就产生无数可能性了。

依赖倒置

类和类之间,只能通过抽象交流。

面向抽象编程,抽象指的是接口或者抽象类。类和类之间不应该依赖于具体的细节,不然会有直接的耦合。

比如说MVP,Presenter和View,就是通过抽象接口进行交互的。

接口隔离

传递对象时,尽可能使用抽象,而不是具体实现类。

如果一个函数,传递了一个具体实现类,那么将会彻底暴露该实现类的方法。

比如说找中介租房,我并不关心中介是如何找房的,我只关心他能不能满足我的要求。这就是中介模式。

我们只要关心接口。

迪米特

只与直接的朋友通信,朋友做了什么具体的事情我不管。

比如图片加载类,一个缓存实现类使用了某第三方工具,但不关我事。就算该类用了其它的第三方工具,我也是无感知的。

总结

六大原则就是提醒我们:
● 一个类别干太多事情了,要分工合作,我们只管制定流程,剩下的由实现类去做
● 一定要擅长面向抽象编程,利用接口和抽象类
● 抽象,可让我们实现千变万化,写具体实现时,别忘记先抽象起来
● 类和类的交互,一定不用依赖具体实现类,而是依赖于抽象类,才有可能具有高扩展性,实现快速替换
● 学会面向抽象编程,才能让系统在无感知的情况下进行悄然改变

当我去审视代码时,发现很多地方可以基于六大原则进行改变。

比如扫码功能,涉及到跳转、扫码、返回数据三块,这三块都被耦合在一个Activity里面。任意一块改变,那么每个Activity都要改一遍。比如我换了个扫码工具,那么都要改一遍。
应该可以把三块抽象出来,让具体类实现逻辑,我们只需制定处理的流程,就可以可以轻松切换了各种不同的实现方式了。我们可以使用模板方法、中介模式、

比如网络功能,我们有可能使用原始的、Retrofit的、第三方工具的方式请求网络,甚至地址是本地的、网络的、mock的,也可以抽象为接口。每个具体的网络请求方式实现接口,我们在进行网络请求时,可以轻松地切换不同的方式。我们可以使用桥接模式,将请求变成原始+本地地址、原始+网络地址、Retrofit+本地地址、Retrofit+网络地址等。

比如说弹出框,我们有自定义的、系统的、第三方的,也可以统统可以抽象出来。我们可以使用工厂模式,想要不同的弹出框,就用工厂给我们生产。

还有其它的:

  • 图片、视频、文件等的选择、浏览、下载功能
  • 线程功能
  • 下拉刷新上拉加载
  • 列表视图
  • 各种选择器
  • 二维码生成工具

这些功能虽然会让我们写很多的抽象类和接口,但是非常方便扩展。
当我们的项目越多或者越大时,好处就越明显。

以上是关于面向对象六大原则,到底在说什么?的主要内容,如果未能解决你的问题,请参考以下文章

面向对象六大原则

中高级面试常驻题:简单说下Java面向对象设计的六大原则

面向对象六大基本原则的理解

面向对象编程的六大原则--单一职责原则

面向对象六大原则及单例模式

面向对象的六大原则