初见感受
见名知意,观察者模式必然有观察者和被观察者。
那么观察者和被观察者分别充当什么角色,他们之间有什么联系呢?
观察者和被观察者之间存在“观察”的逻辑关联,当被观察者发生改变的时候,观察者就会观察到这样的变化,并且做出相应的响应。
概念
观察者模式(有时又被称为模型-视图(View)模式、源-收听者(Listener)模式或从属者模式)是软件设计模式的一种。在此种模式中,一个目标物件(被观察者)管理所有相依于它的观察者物件,并且在它本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现。此种模式通常被用来实现事件处理系统。
举例:
- 用户界面可以作为一个观察者,业务数据是被观察者,用户界面观察业务数据的变化,发现数据变化后,就显示在界面上。
- CCTV广播
- 发布资源
总结:观察者设计模式定义了对象间的一种一对多(一个被观察者,多个观察者)的组合关系,以便一个对象的状态发生变化时,所有依赖于它的对象都得到通知并自动刷新。
简单实现1:
被观察者:Observed_object
/*
* 被观察对象
*/
public class Observed_object {
//被观察的状态,当状态改变时,通知被观察者做出相应的反应
private Integer state;
//观察者们
private Observer_A A;
private Observer_B B;
private Observer_C C;
public Observed_object(Observer_A A,Observer_B B,Observer_C C){
this.A = A;
this.B = B;
this.C = C;
}
public Integer getState() {
return state;
}
public void setState(Integer state) {
this.state = state;
stateChange();
}
//状态发生改变,就通知观察者
public void stateChange() {
A.update(getState());
B.print(getState());
C.calc(getState());
}
}
观察者A:
/*
* 观察者A
*/
public class Observer_A {
public void update(Integer state) {
System.out.println("我是观察者A,"+"目标发生变化,state:"+state+",我将做出update操作");
}
}
观察者B:
/*
* 观察者B
*/
public class Observer_B {
public void print(Integer state) {
System.out.println("我是观察者B,"+"目标发生变化,state:"+state+",我将做出print操作");
}
}
观察者C:
/*
* 观察者C
*/
public class Observer_C {
public void calc(Integer state) {
System.out.println("我是观察者C,"+"目标发生变化,state:"+state+",我将做出clac操作");
}
}
测试:
public class Test {
public static void main(String[] args) {
Observer_A A = new Observer_A();
Observer_B B = new Observer_B();
Observer_C C = new Observer_C();
Observed_object ob_ob = new Observed_object(A, B, C);
ob_ob.setState(0);
ob_ob.setState(1);
ob_ob.setState(2);
}
}
运行结果:
我是观察者A,目标发生变化,state:0,我将做出update操作
我是观察者B,目标发生变化,state:0,我将做出print操作
我是观察者C,目标发生变化,state:0,我将做出clac操作
我是观察者A,目标发生变化,state:1,我将做出update操作
我是观察者B,目标发生变化,state:1,我将做出print操作
我是观察者C,目标发生变化,state:1,我将做出clac操作
我是观察者A,目标发生变化,state:2,我将做出update操作
我是观察者B,目标发生变化,state:2,我将做出print操作
我是观察者C,目标发生变化,state:2,我将做出clac操作
需求改进:
被观察者的状态信息很重要,很多观察者都需要。加入十个新的观察者.
解决1:
如果还按照之前方式,我们将创建十个Observer_x;这样明显不合理
//观察者们
private Observer_A A;
private Observer_B B;
private Observer_C C;
private Observer_D D;
private Observer_E E;
private Observer_F F;
private Observer_G G;
private Observer_H H;
private Observer_I I;
private Observer_J J;
private Observer_K K;
private Observer_L L;
public Observed_object(Integer state, Observer_A a, Observer_B b, Observer_C c, Observer_D d, Observer_E e,
Observer_F f, Observer_G g, Observer_H h, Observer_I i, Observer_J j, Observer_K k, Observer_L l) {
super();
A = a;
B = b;
C = c;
D = d;
E = e;
F = f;
G = g;
H = h;
I = i;
J = j;
K = k;
L = l;
}
改进
所有的观察者都有一个功能,就是观察被观察者发生的变化,随之处理;那么所有的Observer都应该有一个共同的接口;
接口:
public interface Observer {
void update(Integer state);
}
/*
* 观察者A
*/
public class Observer_A implements Observer{
@Override
public void update(Integer state) {
System.out.println("我是观察者A,"+"目标发生变化,state:"+state+",我将做出update操作");
updateMessage(state);
}
public void updateMessage(Integer state) {
}
}
/*
* 观察者B
*/
public class Observer_B implements Observer{
public void print(Integer state) {
//System.out.println("state"+state);
}
@Override
public void update(Integer state) {
System.out.println("我是观察者B,"+"目标发生变化,state:"+state+",我将做出print操作");
print(state);
}
}
/*
* 观察者C
*/
public class Observer_C implements Observer{
public void calc(Integer state) {
//int a = state +state;
//System.out.println("clac操作结果"+a);
}
@Override
public void update(Integer state) {
System.out.println("我是观察者C,"+"目标发生变化,state:"+state+",我将做出clac操作");
calc(state);
}
}
我们在被观察对象中建立一个集合,存放Observer;可以向集合中添加,移除,同时对所有观察者广播
/*
* 被观察对象
*/
public class Observed_object {
//被观察的状态,当状态改变时,通知被观察者做出相应的反应
private Integer state;
//观察者们
private List<Observer> listObserver = new ArrayList<Observer>();
//增加观察者
public void addObserver(Observer o) {
listObserver.add(o);
}
//移除观察者
public void romoveObserver(Observer o) {
listObserver.remove(o);
}
//主动通知观察者发生变化
public void notify(Integer state) {
for (Observer o :listObserver) {
o.update(state);
}
}
public Integer getState() {
return state;
}
public void setState(Integer state) {
this.state = state;
notify(state);
}
}