行为型(四) — 观察者模式

1、定义

Define a one-to-many dependcy between objects so that when one object change state, all its dependents are notified and updated automaticallly.

定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新。

2、使用场景

  1. 关联行为场景,注意,关联行为是可拆分的,而不是“组合”关系
  2. 事件多触发场景
  3. 跨系统的消息交换场景,如:消息队列、事件总线的处理机制

3、UML类图


角色说明:

  1. 抽象主题Subject:被观察者的抽象接口,定义了增加和删除观察者对象
  2. 具体主题ConcreteSubject:具体的被观察者,将所有的具体的观察者登记在一个列表中,当内部状态改变时,给所有登记的观察者发出通知
  3. 抽象观察者Observer:观察者接口,定义了在主题改变时通知自己的接口
  4. 具体观察者ConcreteObserver:实现更新接口

4、示例

以Java中的控件点击事件为例,具体如下:

/**
 * 
 *Clickable 接口对可单击控件功能方法进行了抽象
 *相当 观察者模式的Subjuct
 */
public interface Clickable {
	public void click();
	public void addClickableObserver(ClickableObserver observer);
	public void removeClickableObserver(ClickableObserver observer);
}
/**
 * ClickableObserver 代表可控按键的观察者
 * 相当于观察者模式中的Observer
 *
 */
public interface ClickableObserver {
	// 更新
	public void clicked(Clickable clickable);
}
import java.util.ArrayList;
import java.util.List;

/**
 *   Button 是按钮控件,Button是可点击的,实现了Clickable接口
 *   相当于观察者模式中的ConcreteClickable
 */
public class Button implements Clickable {
	private List<ClickableObserver> observers = new ArrayList<>();
	//  按钮信息
	String color;  // 颜色

	@Override
	public void click() {
        System.out.println("按钮被点击了");
		for(ClickableObserver observer : observers){
			observer.clicked(this);
		}
	}

	@Override
	public void addClickableObserver(ClickableObserver observer) {
		observers.add(observer);
	}

	@Override
	public void removeClickableObserver(ClickableObserver observer) {
		observers.remove(observer);
	}

	@Override
	public String toString() {
		return "Button [color=" + color + "]";
	}
}
/**
 * ChangeColorObserver  修改按钮的颜色值
 *  相当观察者模式的ConcreteObserver
 */
public class ChangeColorObserver implements ClickableObserver {
	@Override
	public void clicked(Clickable clickable) {
		Button button = (Button) clickable;
		button.color = "红色";
	}
}
/**
 * OtherObserver 是其他某种业务操作的观察者
 * 相当观察者模式的ConcreteObserver
 *
 */
public class OtherObserver implements ClickableObserver {

	@Override
	public void clicked(Clickable clickable) {
		System.out.println("执行其他操作");
	}
}
/**
 * Client 测试点击事件
 *
 */
public class Client {

	public static void main(String[] args) {
		Button button = new Button();
		button.color = "白色";
		
		button.addClickableObserver(new ChangeColorObserver());
		button.addClickableObserver(new OtherObserver());
		button.click();
		
		System.out.println(button.toString());
	}
}

结果输出如下:

按钮被点击了
执行其他操作
Button [color=红色]

5、总结

优点:

  1. 观察者和被观察者之间是抽象耦合的
  2. 增加系统灵活性,可扩展性

缺点:

  1. 在Java中消息通知默认是顺序执行的,一个观察者卡顿,会影响整个的执行效率。在这种情况下,采用异步的方式。

猜你喜欢

转载自blog.csdn.net/zcjxaiofeizhu/article/details/80789775