本文列举几个Android源码中的设计模式。

设计模式分为创建型模式、结构型模式、行为型模式。

创建型模式

单例模式

单例在Android开发中经常用到,但是表现形式可能不太一样。

以ActivityManager等系统服务来说,是通过静态代码块的形式实现单例,在首次加载类文件时,生成单例对象,然后保存在Cache中,之后的使用都是直接从Cache中获取。

1
2
3
4
5
6
7
8
9
10
11
class ContextImpl extends Context {
static {
registerService(ACTIVITY_SERVICE, new ServiceFetcher() {
public Object createService(ContextImpl ctx) {
return new ActivityManager(ctx.getOuterContext(), ctx.mMainThread.getHandler());
}});
}
}
```
当然,还有更加明显的例子,比如AccessibilityManager内部自己也保证了单例,使用getInstance获取单例对象。

public static AccessibilityManager getInstance(Context context) {
synchronized (sInstanceSync) {
if (sInstance == null) {

           ......

            IBinder iBinder = ServiceManager.getService(Context.ACCESSIBILITY_SERVICE);
            IAccessibilityManager service = iBinder == null
                    ? null : IAccessibilityManager.Stub.asInterface(iBinder);
            sInstance = new AccessibilityManager(context, service, userId);
        }
    }
    return sInstance;
}
1
2
3
4
5
6
7
8
### 工厂方法模式
静态工厂方法在Android中比较明显的例子应该就是**BitmapFactory**了,通过各种decodeXXX()就可以从不同渠道获得Bitmap对象
### 原型模式
书中以Intent介绍了原型模式,是通过实现Cloneable接口来做的

public class Intent implements Parcelable, Cloneable {
@Override
public Object clone() {
return new Intent(this);
}
}

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
### Builder模式
工厂类模式提供的是创建单个类的模式,而建造者模式则是将各种产品集中起来进行管理,用来创建复合对象, 所谓复合对象就是指某个类具有不同的属性,其实建造者模式就是前面抽象工厂模式和最后的 Test 结合起来得到的
在Android源码中,我们最常用到的Builder模式就是AlertDialog.Builder, 使用该Builder来构建复杂的AlertDialog对象。
## 行为型模式
### 责任链模式
书中对于责任链模式选取的例子非常有代表性,那就是Android的触摸机制,这个看法让我从另一个维度去理解Android中的触摸事件传递。
### 观察者模式
书中介绍观察者模式使用的是**ListView的Adapter**为例子,我之前知道Adapter属于适配器模式,不知道这里还有观察者模式的身影,学到了。
Android里面的各种监听器,也都属于观察者模式,比如触摸、点击、按键等,ContentProvider和广播接收者也有观察者模式的身影,可以说是无处不在。
除此之外,现在很多基于观察者模式的第三方框架也是非常多,比如EventBus、RxJava等等,都是对观察者模式的深入使用,感兴趣的同学可以研究一下。
### 模板方法模式
对Activity生命周期的理解。
### 命令模式
Command接口中定义了一个execute方法,客户端通过Invoker调用命令操作再来调用Recriver执行命令;把对Receiver的操作请求封装在具体的命令中,使得命令发起者和命令接收者解耦。 以Android中大家常见的Runnable为例:客户端只需要new Thread(new Runnable(){}).start()就开始执行一系列相关的请求,这些请求大部分都是实现Runnable接口的匿名类。 【O_o 模式就在我们身边~】
## 结构型模式
### 代理模式和装饰器模式
1. 装饰器模式关注于在一个对象上动态的添加方法,而代理模式关注于控制对对象的访问
> 顾名思义,装饰模式就是给一个对象增加一些新的功能,而且是动态的,要求装饰对象和被装饰对象实现同一个 接口,装饰对象持有被装饰对象的实例。
2. 代理模式,代理类可以对它的客户隐藏一个对象的具体信息。因此,当使用代理模式的时候,我们常常在一个代理类中创建一个对象的实例。而当我们使用装饰器模式的时候,通常的做法是将原始对象作为一个参数传给装饰者的构造器,和适配器模式的区别:适配器模式主要改变所考虑对象的接口,而代理模式不能改变所代理类的接口2、和装饰器模式的区别:装饰器模式为了增强功能,而代理模式是为了加以控制。
**WindowManagerImpl就是一个代理类**:

public final class WindowManagerImpl implements WindowManager {
private final WindowManagerGlobal mGlobal = WindowManagerGlobal.getInstance();
private final Display mDisplay;
private final Window mParentWindow;

......

@Override
public void addView(View view, ViewGroup.LayoutParams params) {
    mGlobal.addView(view, params, mDisplay, mParentWindow);
}

@Override
public void updateViewLayout(View view, ViewGroup.LayoutParams params) {
    mGlobal.updateViewLayout(view, params);
}

@Override
public void removeView(View view) {
    mGlobal.removeView(view, false);
}

@Override
public void removeViewImmediate(View view) {
    mGlobal.removeView(view, true);
}

@Override
public Display getDefaultDisplay() {
    return mDisplay;
}

}

1
2
3
4
从上面的代码中可以看出,大部分WindowManagerImpl的方法都是通过WindowManagerGlobal实现的,而WindowManagerGlobal对象不需要额外的赋值,就存在于WindowManagerImpl中。另外,WindowManagerGlobal中其实有大量的方法,但是通过WindowManagerImpl代理之后,都没有暴露出来,对开发者是透明的。
书中是以Context和它的包装类ContextWrapper讲解的,也非常的典型:

public class ContextWrapper extends Context {
Context mBase;

public ContextWrapper(Context base) {
    mBase = base;
}

}
```

外观模式(Facade)

在开发过程中,Context是最重要的一个类型。它封装了很多重要的操作,比如startActivity()、sendBroadcast()等,几乎是开发者对应用操作的统一入口。Context是一个抽象类,它只是定义了抽象接口,真正的实现在ContextImpl类中。它就是今天我们要分析的外观类。

适配器模式

适配器模式将某个类的接口转换成客户端期望的另一个接口表示,目的是消除由于接口不匹配所造成的类的兼容 性问题。主要分为三类:类的适配器模式、对象的适配器模式、接口的适配器模式。