Android-面向对象6大原则源码设计模式

单一职责原则——优化代码第一步

Single Responsibility Principle, SRP. 就一个类而言,应该仅有一个能引起他变化的原因。最重要的是,要能划分一个类具体的职责,2个完全不同的功能代码不能放在同一个类中,会引起类文件冗余庞大,后面的代码会越来越难以维护,这是优化代码第一步。例如我们去写一个缓存图片的功能。

1、下载图片 2、缓存图片

在这里基础的用3个类文件去写,download、cache、tools,写在一个文件就会显得特别的大,这样后续开发看着就头大,找代码就要找半天,写3个文件非常简洁,可以在把这三个文件放到一个package里面去。这样不管开发还是后续维护都很容易。

开闭原则——-让程序稳定和灵活

Open Close Principle,OCP。代码文件对于修改是封闭的,但对于扩展是开放的。也就是说,尽可能的不去修改原来旧文件,因为一旦修改,别的对象调用会出现问题,因为你不知道这个函数方法在哪里调用会被调用几次(总不能一直点击去查看吧,或者写很多个注释)。但是对象调用肯定会使用到当前类文件,为了满足后续需求,所以他的拓展性是要开放的,一般使用接口满足拓展性。

里氏替换原则—–构建拓展性更好的系统

所有引用基类的地方必须能透明的使用其子类的对象。面向对象的三大特性:封装、继承、多态。里氏替换原则就是基于多态和继承,只要父类出现的地方子类就可以出现,而且替换为子类也不会有任何的错误和异常。其实就是一种抽象。看下面一个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
public class Test {
public static void main(String[] args) {
Window window = new Window();
window.show(new Button());
window.show(new TextView());
}
public static class Window{
public void show(View child){
child.mesure();
child.draw();
}
}
//写一个抽象view,draw交给子类自己实现,mesure公用代码
public static abstract class View{
public void mesure(){
print("view mesure");
}
public abstract void draw();
}
//写一个Button
public static class Button extends View{
@Override
public void draw() {
print("button draw");
}
}
//新建一个TextView文件
public static class TextView extends View{
@Override
public void draw() {
print("textview draw");
}
}
public static void print(String message){
System.out.println(message);
}
}
//执行结果
view mesure
button draw
view mesure
textview draw

可以仔细看看这段代码,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源码设计模式第一步,就是必须对这些基本原理理解透彻。


Android-面向对象6大原则源码设计模式
http://example.com/1979/11/30/Android-源码设计模式-面向对象6大原则/
作者
xdd
发布于
1979年11月30日
许可协议