观察者模式(发布/订阅模式):
提供了避免组件之间紧密耦合的另一种方法,它将观察者和被观察者的对象分离开。
在这模式中:
一个对象通过添加一个方法(该方法允许另一个对象,即观察者注册自己)使得本身变得可观察。当可观察的对象更改时,它会将消息发送到已注册的观察者。
这些观察者收到消息后执行的操作与可观察的对象无关。
使得对象可以相互对话,而不必了解原因。
事件处理机制采用这种设计模式
在模块之间划分了清晰的界限,提高了应用程序的可维护性和重用性。
//Observer : 观察者接口,具体的观察者会实现这个接口。
public interface Observer {
public abstract void update(NumberGenerator generator);
}
/*
* NumberGenerator: 表示生成数值的对象的抽象类
*/
public abstract class NumberGenerator {
private ArrayList observers = new ArrayList(); //保存观察者
//注册观察者: 加入到ArrayList数组中
public void addObserver(Observer observer){
observers.add(observer);
}
//删除观察者
public void deleteObserver(Observer observer){
observers.remove(observer);
}
//向观察者发通知
public void notifyObservers(){
Iterator iterator = observers.iterator();
while(iterator.hasNext()){
//遍历数组中的观察者,并获取该对象,调用update方法发通知
Observer o = (Observer)iterator.next();
o.update(this);
}
}
//生成数值的方法: 具体子类实现
public abstract void execute();
//获取数值的方法: 具体子类实现
public abstract int getNumber();
}
/*
* 作为NumberGeneratror的子类,实现了生成随机数功能,即execute()方法
*/
public class RandomNumberGeneratror extends NumberGenerator{
private Random random = new Random();
private int number;
@Override
public void execute() {
for (int i = 0; i < 20; i++) {
number = random.nextInt(50);
//调用通知功能
notifyObservers();
}
}
@Override
public int getNumber() {
return number;
}
}
/*
* 实现了Observer接口,主要作用:以数字形式显示观察到的数值,是一个观察者
*/
public class DigitObserver implements Observer{
@Override
public void update(NumberGenerator generator) {
//获取数值
System.out.println("DigitObserver: " + generator.getNumber());
try{
Thread.sleep(100);
}catch(InterruptedException e){}
}
}
//另一个观察者
public class GraphObserver implements Observer{
@Override
public void update(NumberGenerator generator) {
System.out.println("GraphObserver: ");
int count = generator.getNumber();
for (int i = 0; i < count; i++) {
System.out.print("*");
}
System.out.println();
try{
Thread.sleep(100);
}catch(InterruptedException e){}
}
}
//测试
public class Test1 {
public static void main(String[] args) {
NumberGenerator generator = new RandomNumberGeneratror();
DigitObserver observer1 = new DigitObserver();
GraphObserver observer2 = new GraphObserver();
generator.addObserver(observer1);
generator.addObserver(observer2);
generator.execute();
}
}
-
generator.execute():执行的是RandomNumberGeneratror类中的execute()方法。
-
RandomNumberGeneratror类中的execute()方法,又触发NumberGenerator类中的notifyObservers()方法。
-
NumberGenerator类中的notifyObservers()方法又触发Observer类中的update方法,并且传入的是RandomNumberGeneratror类的对象,Observer中的update()方法由其具体的子类实现,所以会触发DigitObserver类和GraphObserver类中的update()方法。
-
DigitObserver类中的update()方***使用传入的形参调用getNumber()方法获取数值,这个形参就是RandomNumberGeneratror类对象。
-
RandomNumberGeneratror类对象会调用getNumber()方法获取本次生成的随机数,并作为返回值返回给DigitObserver类中。DigitObserver类就获取了getNumber()返回的数值,另一个GraphObserver类也同样如此。