观察者模式
什么是观察者模式?
定义对象间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新。观察者模式又叫做发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听器(Source/Listener)模式或从属者(Dependents)模式。观察者模式是一种对象行为型模式。
简单举例:
- 问题: 假设猫是老鼠和狗的观察目标,老鼠和狗是观察者,猫叫老鼠和狗也有相应的反应,使用观察者模式描述该过程。
- 分析:
- 写一个抽象的猫类,作为被观察者,也就是观察目标,你的一举一动要被观察你的东西知道,他们如何知道呢?这就需要你的通知。所以每一个观察者都要在你这里注册一下才能给他们通知。
- 观察者观察的就是你的一举一动,也就是你的状态,你要有得到状态的方法,方便他们知道。
- 要有一个抽象观察者类,抽象的更新方法。
- 具体实现观察者类时不妨把观察目标传进来,以便得到他们的状态。
- 图示:
- 代码:
package guanchazhemoshi;
public abstract class Cat {
public abstract void add(Observer observer);
public abstract void remove(Observer observer);
public abstract void miao(int sound);
}
package guanchazhemoshi;
public interface Observer {
public abstract void update();
}
package guanchazhemoshi;
public class State {
String s;
public State(int sound) {
if(sound==1){s="好饿";}
else if(sound==2){s="无聊";}
else if(sound==3){s="生气";}
}
public String gets(){
return s;
}
}
package guanchazhemoshi;
public class Mouse implements Observer{
private TomCat cat;
Mouse(TomCat cat){
this.cat = cat;
}
public void update(){
String s = cat.getState().gets();
if(s=="好饿"){
System.out.println("老鼠:那只猫又饿了,我得藏起来");
}
if(s=="无聊"){System.out.println("老鼠:呵呵");}
if(s=="生气"){System.out.println("老鼠:哈哈,傻猫,气死你");}
}
}
package guanchazhemoshi;
public class Dog implements Observer{
private TomCat cat;
Dog(TomCat cat){
this.cat = cat;
}
public void update(){
String s = cat.getState().gets();
if(s=="好饿"){
System.out.println("狗:懒猫,饿死你");
}
if(s=="无聊"){System.out.println("狗:无聊去抓老鼠呀");}
if(s=="生气"){System.out.println("狗:不敢惹,离你远点");}
}
}
package guanchazhemoshi;
import java.util.ArrayList;
public class TomCat extends Cat {
ArrayList<Observer> list = new ArrayList<Observer>();
State state;
/*
* 注册观察者
*/
public void add(Observer observer) {
list.add(observer);
}
/*
* 删除观察者
*/
public void remove(Observer observer) {
list.remove(observer);
}
/*
* 不同的猫叫声大小代表不同的状态,以此通知观察者
*/
public void miao(int sound) {
this.setState(sound);
for(Observer observer:list){
observer.update();
}
}
/*
* 根据声音大小设置状态
*/
public void setState(int sound){
state = new State(sound);
}
/*
* 得到当前状态
*/
public State getState(){
return state;
}
}
package guanchazhemoshi;
public class Client {
public static void main(String[] args) {
TomCat c = new TomCat();
Mouse m = new Mouse(c);
Dog d = new Dog(c);
c.add(m);
c.add(d);
c.miao(1);
c.miao(2);
c.miao(3);
}
}
老鼠:那只猫又饿了,我得藏起来
狗:懒猫,饿死你
老鼠:呵呵
狗:无聊去抓老鼠呀
老鼠:哈哈,傻猫,气死你
狗:不敢惹,离你远点