策略模式的精髓就在于,你传入一个类,后面的处理就能按照这个类的实现去做。以动画为例,设置不同的插值器对象,就可以得到不同的变化曲线;以返回值解析为例,传入什么样的解析器,就可以把二进制数据转换成什么格式的数据,比如String、Json、XML。
责任链模式书中对于责任链模式选取的例子非常有代表性,那就是Android的触摸机制,这个看法让我从另一个维度去理解Android中的触摸事件传递。
我在这里提到这个模式,并不想说太多,只是简单的推荐你读一下这一章的内容,相信你也会有收获的。
观察者模式Android中的观察者模式应该是用的非常频繁的一种模式了,对于这个模式的使用场景就一句话:你想在某个对象发生变化时,立刻收到通知。
书中介绍观察者模式使用的是ListView的Adapter为例子,我之前知道Adapter属于适配器模式,不知道这里还有观察者模式的身影,学到了。
Android里面的各种监听器,也都属于观察者模式,比如触摸、点击、按键等,ContentProvider和广播接收者也有观察者模式的身影,可以说是无处不在。
除此之外,现在很多基于观察者模式的第三方框架也是非常多,比如EventBus、RxJava等等,都是对观察者模式的深入使用,感兴趣的同学可以研究一下。
模板方法模式这个模式我之前见的比较少,但是理解之后,就会发现这个模式很简单。
我觉得,模板方法模式的使用场景也是一句话:流程确定,具体实现细节由子类完成。
这里要关注一下『流程』这个关键字,随便拿一个抽象类,都符合”具体实现细节由子类完成”的要求,关键就在于是否有流程,有了流程,就叫模板方法模式,没有流程,就是抽象类的实现。
书中讲这个模式用的是AsyncTask,各个方法之间的执行符合流程,具体实现由我们完成,非常经典。
另外一个方面,Activity的生命周期方法可以看做是模板方法模式,各个生命周期方法都是有顺序的,具体实现我们可以重写,是不是和前面的要求很符合?关于这方面的理解,可以参考我的这篇文章:对Activity生命周期的理解。
除了Android里面的模板方法模式,在其他开源项目中也存在着这个模式的运用。比如鸿洋的OkHttp-Utils项目,就是模板方法模式的典型实现。将一个Http请求的过程分割成几部分,比如获取URL,获取请求头,拼接请求信息等步骤,这几个步骤之前有先后顺序,就可以这样来做。
代理模式和装饰器模式之所以把这两个放在一起说,是因为这两种模式很像,所以这里简单介绍下他们之间的区别,主要有两点。
这两句话可能不太好理解,没关系,下面看个例子。
代理模式会持有被代理对象的实例,而这个实例一般是作为成员变量直接存在于代理类中的,即不需要额外的赋值。
比如说WindowManagerImpl就是一个代理类,虽然名字上看着不像,但是它代理的是WindowManagerGlobal对象。从下面的代码中就可以看出来。
{ private final WindowManagerGlobal mGlobal = WindowManagerGlobal.getInstance(); private final Display mDisplay; private final Window mParentWindow; ...... (View view, ViewGroup.LayoutParams params) { mGlobal.addView(view, params, mDisplay, mParentWindow); } (View view, ViewGroup.LayoutParams params) { mGlobal.updateViewLayout(view, params); } (View view) { mGlobal.removeView(view, false); } (View view) { mGlobal.removeView(view, true); } @Override public Display getDefaultDisplay() { return mDisplay; } }从上面的代码中可以看出,大部分WindowManagerImpl的方法都是通过WindowManagerGlobal实现的,而WindowManagerGlobal对象不需要额外的赋值,就存在于WindowManagerImpl中。另外,WindowManagerGlobal中其实有大量的方法,但是通过WindowManagerImpl代理之后,都没有暴露出来,对开发者是透明的。
我们再来看一下装饰器模式。装饰器模式的目的不在于控制访问,而是扩展功能,相比于继承基类来扩展功能,使用装饰器模式更加的灵活。
书中是以Context和它的包装类ContextWrapper讲解的,也非常的典型,我这里就不在赘述了,贴出一些代码来说明装饰器模式的形式。
{ Context mBase; public ContextWrapper(Context base) { mBase = base; } }但是还有一个问题,就是在ContextWrapper中,所有方法的实现都是通过mBase来实现的,形式上是对上号了,说好的扩展功能呢?
功能扩展其实是在ContextWrapper的子类ContextThemeWrapper里面。
在ContextWrapper里面,获取系统服务是直接通过mBase完成的
@Override public Object getSystemService(String name) { return mBase.getSystemService(name); }但是在ContextThemeWrapper里面,对这个方法进行了重写,完成了功能扩展
@Override public Object getSystemService(String name) { if (LAYOUT_INFLATER_SERVICE.equals(name)) { if (mInflater == null) { mInflater = LayoutInflater.from(getBaseContext()).cloneInContext(this); } return mInflater; } return getBaseContext().getSystemService(name); }当然,如果不存在功能扩展就不算是装饰器模式了吗?其实设计模式本来就是『仁者见仁,智者见智』的事情,只要你能理解这个意思就好。
外观模式外观模式可能看到的比较少,但是其实不经意间你就用到了。