首页 > 代码库 > 设计模式大类--行为模式(上)

设计模式大类--行为模式(上)

  大概有10中行为模式,分为上中下三篇。
一、Template(模板)
描述:定义一些操作算法的骨架,将其实现延迟到其子类
好处:扩展性强

例子:
Java的抽象类本来就是Template模式,因此使用很普遍.而且很容易理解和使用,我们直接以示例开始:

public abstract class Benchmark
{
  /**
  * 下面操作是我们希望在子类中完成
  */
  public abstract void benchmark();

  /**
  * 重复执行benchmark次数
  */
  public final long repeat (int count) {
    if (count <= 0)
      return 0;
    else {
      long startTime = System.currentTimeMillis();

    for (int i = 0; i < count; i++)
      benchmark();

    long stopTime = System.currentTimeMillis();
    return stopTime - startTime;
  }
}
}

在上例中,我们希望重复执行benchmark()操作,但是对benchmark()的具体内容没有说明,而是延迟到其子类中描述:

public class MethodBenchmark extends Benchmark
{
  /**
  * 真正定义benchmark内容
  */
  public void benchmark() {

    for (int i = 0; i < Integer.MAX_VALUE; i++){
      System.out.printtln("i="+i);    
    }
  }
}

至此,Template模式已经完成,是不是很简单?看看如何使用:

Benchmark operation = new MethodBenchmark();
long duration = operation.repeat(Integer.parseInt(args[0].trim()));
System.out.println("The operation took " + duration + " milliseconds");

二、Memento(备忘录)
描述:保存另外一个对象内部状态拷贝的对象.这样以后就可以将该对象恢复到原先保存的状态
好处:要保存的细节给封装在了Memento中,不对外暴露封装的细节,哪一天要改保存的细节也不用影响客户端了

例子:
public class Originator {

   private int number;

  private File file = null;

  public Originator(){}

  // 创建一个Memento
  public Memento getMemento(){
    return new Memento(this);
  }

  // 恢复到原始值
  public void setMemento(Memento m){
     number = m.number;
     file = m.file;
  }

}


我们再看看Memento类:

private class Memento implements java.io.Serializable{

  private int number;

  private File file = null;

  public Memento( Originator o){

    number = o.number;
    file = o.file;

  }

}


可见 Memento中保存了Originator中的number和file的值. 通过调用Originator中number和file值改变的话,通过调用setMemento()方法可以恢复.

Memento模式的缺点是耗费大,如果内部状态很多,再保存一份,无意要浪费大量内存.

三、Observer(观察者)
描述:定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象,主题对象在状态上发生变化时,会通知所有观察者对象,让它们能够自动更新自己
好处:观察者模式在被观察者和观察者之间建立一个抽象的耦合;观察者模式支持广播通讯。被观察者会向所有的登记过的观察者发出通知。

例子:
首先定义抽象的观察者:

//抽象观察者角色
public interface Watcher
{
public void update(String str);

}
  然后定义抽象的主题角色,即抽象的被观察者,在其中声明方法(添加、移除观察者,通知观察者):


//抽象主题角色,watched:被观察
public interface Watched
{
public void addWatcher(Watcher watcher);

public void removeWatcher(Watcher watcher);

public void notifyWatchers(String str);

}

  然后定义具体的观察者:

public class ConcreteWatcher implements Watcher
{

@Override
public void update(String str)
{
System.out.println(str);
}

}

  之后是具体的主题角色: 


import java.util.ArrayList;
import java.util.List;

public class ConcreteWatched implements Watched
{
// 存放观察者
private List<Watcher> list = new ArrayList<Watcher>();

@Override
public void addWatcher(Watcher watcher)
{
list.add(watcher);
}

@Override
public void removeWatcher(Watcher watcher)
{
list.remove(watcher);
}

@Override
public void notifyWatchers(String str)
{
// 自动调用实际上是主题进行调用的
for (Watcher watcher : list)
{
watcher.update(str);
}
}

}

  编写测试类:


public class Test
{
public static void main(String[] args)
{
Watched girl = new ConcreteWatched();

Watcher watcher1 = new ConcreteWatcher();
Watcher watcher2 = new ConcreteWatcher();
Watcher watcher3 = new ConcreteWatcher();

girl.addWatcher(watcher1);
girl.addWatcher(watcher2);
girl.addWatcher(watcher3);

girl.notifyWatchers("开心");
}

}