1、简单工厂模式——代码摘自《大话设计模式》
将业务与客户端代码分离
业务Operation操作类
业务加减乘除类
业务简单运算工厂类
客户端代码
业务UML图
2、代理模式——代码摘自《大话设计模式》
场景如下:追求者,被追求者,代理3个人,追求者要追求被追求者,委托代理送花等进行一系列追求的动作。
代理与被代理者结构图
共同实现的接口
追求者
代理类
客户端代码
UML图
应用
Android中的客户端访问系统服务,和facebook提供的thriftdou是典型的代理模式,用于远程调用。
3、观察者模式(也叫发布订阅模式)
以Android为例,典型的观察者模式的应用是DataSetObservable和DataSetObserver这两个类。DataSetObservable表示被观察者,DataSetObserver表示观察者。
DataSetObservable继承自抽象类Observable,先从Observable说起。
Observable是一个带泛型的抽象类。表示一个观察者对象,提供了观察者注册、注销及清空三个方法。其源码如下:
public abstract class Observable{ protected final ArrayList mObservers = new ArrayList (); public void registerObserver(T observer) { if (observer == null) { throw new IllegalArgumentException("The observer is null."); } synchronized(mObservers) { if (mObservers.contains(observer)) { throw new IllegalStateException("Observer " + observer + " is already registered."); } mObservers.add(observer); } } public void unregisterObserver(T observer) { if (observer == null) { throw new IllegalArgumentException("The observer is null."); } synchronized(mObservers) { int index = mObservers.indexOf(observer); if (index == -1) { throw new IllegalStateException("Observer " + observer + " was not registered."); } mObservers.remove(index); } } public void unregisterAll() { synchronized(mObservers) { mObservers.clear(); } }}
Observable的直接继承者有两个:DataSetObservable和ContentObservable。ContentObservable实现比较复杂,不过功能与DataSetObservable类似,这里只讲解DataSetObservable。
DataSetObservable在很多的Adapter中都用到,像BaseAdapter。
DataSetObserver表示了一个数据集对象的观察者,主要提供了两个方法:
public abstract class DataSetObserver { public void onChanged() { // Do nothing } public void onInvalidated() { // Do nothing }}
DataSetObservable实现如下:
public class DataSetObservable extends Observable{ public void notifyChanged() { synchronized(mObservers) { // since onChanged() is implemented by the app, it could do anything, including // removing itself from {@link mObservers} - and that could cause problems if // an iterator is used on the ArrayList {@link mObservers}. // to avoid such problems, just march thru the list in the reverse order. for (int i = mObservers.size() - 1; i >= 0; i--) { mObservers.get(i).onChanged(); } } } public void notifyInvalidated() { synchronized (mObservers) { for (int i = mObservers.size() - 1; i >= 0; i--) { mObservers.get(i).onInvalidated(); } } }}
当数据集有变化时,会调用DataSetObserver的onChanged()方法;当数据集失效时,会调用DataSetObserver的onInvalidated()方法。
4、模板方法模式
模板方法模式是用来提炼代码的。在提炼代码的过程中会用到abstract方法。
举个《大话设计模式》中的例子。学生抄写试卷,并回答问题。代码冗余的做法:
学生甲的试卷:
学生乙的试卷:
客户端代码:
从上可以看出,代码非常冗余,将代码进行提炼,得到如下代码:
抽象出的父类代码:
学生子类代码:
客户端代码和上面的相同。
以上的代码还可以再提炼。
客户端代码为:
模板方法抽象代码:
UML图如下:
模板方法模式是通过把不变行为搬移到超类,去除子类中的重复代码来体现它的优势。
模板方法模式就是提供了一个很好的代码复用平台。
当不变的和可变的行为在方法的子类实现中混合在一起的时候,不变的行为就会在子类中重复出现,我们通过模板方法模式把这些行为搬移到单一的地方,这样就帮助子类摆脱重复的不变行为的纠缠。