Android-面向对象6大原则源码设计模式
单一职责原则——优化代码第一步
Single Responsibility Principle, SRP. 就一个类而言,应该仅有一个能引起他变化的原因。最重要的是,要能划分一个类具体的职责,2个完全不同的功能代码不能放在同一个类中,会引起类文件冗余庞大,后面的代码会越来越难以维护,这是优化代码第一步。例如我们去写一个缓存图片的功能。
1、下载图片
2、缓存图片
在这里基础的用3个类文件去写,download、cache、tools,写在一个文件就会显得特别的大,这样后续开发看着就头大,找代码就要找半天,写3个文件非常简洁,可以在把这三个文件放到一个package里面去。这样不管开发还是后续维护都很容易。
开闭原则——-让程序稳定和灵活
Open Close Principle,OCP。代码文件对于修改是封闭的,但对于扩展是开放的。也就是说,尽可能的不去修改原来旧文件,因为一旦修改,别的对象调用会出现问题,因为你不知道这个函数方法在哪里调用会被调用几次(总不能一直点击去查看吧,或者写很多个注释)。但是对象调用肯定会使用到当前类文件,为了满足后续需求,所以他的拓展性是要开放的,一般使用接口满足拓展性。
里氏替换原则—–构建拓展性更好的系统
所有引用基类的地方必须能透明的使用其子类的对象。面向对象的三大特性:封装、继承、多态。里氏替换原则就是基于多态和继承,只要父类出现的地方子类就可以出现,而且替换为子类也不会有任何的错误和异常。其实就是一种抽象。看下面一个例子:
1 |
|
可以仔细看看这段代码,Window中的show(View child),在这里传入的是View的子类Button和Textview对象。
mesure()是子类调用父类方法,这是一个公共的方法,因为你不用每个view子类都自己去测量,在父View中共用一套代码执行就完毕。
draw()是子类方法,子类继承抽象父类必须实现的抽象方法,这里面每个View都有自己的绘制方法,所以需要每个子类都去自定义。
这就是里氏替换原则,用的正是面向对象三大特性之二的继承和多态。继承是父类里面的共有方法,多态体现在任何使用基类的地方都可以创建其子类对象。
里氏替换原理就是抽象,抽象又依赖继承这个特性,继承的优点
代码重用,减少创建类的成本,每个子类都有父类的属性和方法;
子类和父类相似,但和父类有区别;
提高代码的可扩展性
继承的缺点
继承是侵入性的,只要继承就必须拥有父类的所有属性和方法;
可能造成子类的代码冗余,因为子类必须拥有父类的属性和方法;
依赖倒置原则——让项目拥有变换的能力
依赖倒置原则是一种特定的解藕形式,使得高层次模块不依赖于低层次模块的实现细节,依赖模块被颠倒了。
1、高层模块不应该依赖底层模块,两者都应该依赖其抽象;
2、抽象不应该依赖细节;
3、细节应该依赖抽象;
在java中,抽象就是指的接口或者抽象类,两者都是不能背实例化的;细节就是实现类,实现接口或者继承抽象类产生的类就是细节,是可以被实例化的。高层模块就是调用端,底层模块就是细节类。
模块间的依赖通过抽象产生,实现类之间不发生直接的依赖关系,其依赖关系是通过接口或抽象类产生的,也就是面向接口或者面向抽象编程
接口隔离原则——-系统拥有更高的灵活度
ISP定义:客户端不应该依赖他不需要的接口,或者类之间的关系应该建立在最小的接口上。接口隔离的原则是让庞大冗余的接口拆分为更小、更加精细的接口,让接口尽可能的小。这个在实际的引用场景还是常见的,如closeable.close()等。
单一职责、开闭原则、里氏替换、接口隔离和依赖倒置这5个原则常见于Android源码之中,其特点为:抽象、单一职责、最小化。也就是说,类之间的依赖关系应该基于抽象,单个类符合单一职责,单个类和方法也要最小化。
迪米特原则——更好的可扩展性
最少知识原则,一个对象对其他对象应该有最少的了解,一个类应该对和自己耦合的类知道的最少。
这个实际应用也很广泛,多个文件相互通信时,不应该一股脑全部都写出来,而是确定一个方向,和当前类耦合度最低,调用的文件越少愈好。从mvp到mvvm不就是这样的设计模式🐎
总结
应用实际开发中,最难的不是初始开发工作,而是后续的迭代和升级,越来越多的代码文件加入其中,类文件越来越臃肿时。这时候就是考验对这6大原则掌握的时候了,不管是重构还是新加入的文件,遵循这6大原则会让代码简介、清晰、灵活和稳定。所谓高内聚、低耦合和高扩展度就是如此。阅读Android源码设计模式第一步,就是必须对这些基本原理理解透彻。