观察者模式——————个人理解

1、观察者模式会分别定义一个主题接口Subject和观察者接口Observer。
2、主题接口:一般有add()添加观察者、del()删除观察者、notify()通知观察者。
为什么要有add( )、del( )方法呢?因为有新的观察者添加进来,你要在主题接口里新建
一个List<Object> 把他们存起来,需要通知观察者,就遍历list来通知所有。删除就是有人
不想观察了就从list中remove掉。
3、观察者接口:有一个updata()方法。
4、主体实现类:在其方法中对观察者的调用都是依赖Observer接口,利用多态实现
对观察者实现类的操作。利用对象数组方式对众多观察者对象进行存储。
5、观察者实现类:可以有多个,分别实现Observer接口。观察者可以在构造函数中调用主题
中的add方法,也可以在Test中调用。当被通知更新时就是被调用updata()方法。
不同观察者在实现接口中的updata方法时,可以有不同的实现。


代码如下:
//主题接口
public interface Subject {
	void add(Observer o);
	void del(Observer o);
	void call();
//实现主题
public class WeatherData implements Subject {
	private List<Object> list;
	private float w;
	private float s;
	private float p;
	public WeatherData() {
		list = new ArrayList<Object>();
	}


	@Override
	public void add(Observer o) {
		list.add(o);
	}


	@Override
	public void del(Observer o) {
		int i=list.indexOf(o);
		if(i>=0){
		list.remove(i);
		}
	}


	@Override
	public void call() {
		for(int i=0;i<list.size();i++){
			Observer obs=(Observer)list.get(i);
			obs.updata(w, s, p);
			
		}
	}
	
	public void setTemp(float w,float s,float p){
		this.w=w;
		this.s=s;
		this.p=p;
		call();
	}


}


}


//观察者接口
public interface Observer {
	void updata(float w,float s,float p);
}


//观察者接口的具体实现
public class CurrentDisplay implements Observer {
	private float w;
	private float s;
	private Subject wd;


	public CurrentDisplay(Subject wd) {
	
		this.wd=wd;
		wd.add(this);
		
	}


	@Override
	public void updata(float w, float s, float p) {
		this.w=w;
		this.s=s;
		display();
	}
	public void display(){
		System.out.println("w= "+w+"s= "+s);
	}


}


public class Test {
	public static void main(String[] args) {
		WeatherData s=new WeatherData();
		
		Observer o=new CurrentDisplay(s);
		
		
		s.setTemp(30.0f, 0.8f, 100.0f);
		
		
	}


}





小结:观察者模式是一种一对多关系,主题只有一个,而观察者众多。主题与观察者之间的
      依赖都是通过父类接口实现,这样可以达到松耦合的目的。


观察者模式的效果有以下的优点:
第一、观察者模式在被观察者和观察者之间建立一个抽象的耦合。被观察者角色所知道的只是一个具体
      观察者列表,每一个具体观察者都符合一个抽象观察者的接口。被观察者并不认识任何一个具
      体观察者,它只知道它们都有一个共同的接口。由于被观察者和观察者没有紧密地耦合在一起,
      因此它们可以属于不同的抽象化层次。如果被观察者和观察者都被扔到一起,
      那么这个对象必然跨越抽象化和具体化层次。
第二、观察者模式支持广播通讯。被观察者会向所有的登记过的观察者发出通知,

观察者模式有下面的缺点:
第一、如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。
第二、如果在被观察者之间有循环依赖的话,被观察者会触发它们之间进行循环调用,导致系统崩溃。
      在使用观察者模式是要特别注意这一点。
第三、如果对观察者的通知是通过另外的线程进行异步投递的话,系统必须保证投递是以自恰的方式进行的。
第四、虽然观察者模式可以随时使观察者知道所观察的对象发生了变化,但是观察者模式没有相应的机制
      使观察者知道所观察的对象是怎么发生变化的。



在要说的分歧在这里:

“推”push 的方式是指,Subject维护一份观察者的列表,每当有更新发生,Subject会把更新消息主动推送到各个Observer去。

“拉”pull 的方式是指,各个Observer维护各自所关心的Subject列表,自行决定在合适的时间去Subject获取相应的更新数据。


“推”的好处包括:
1、高效。如果没有更新发生,不会有任何更新消息推送的动作,即每次消息推送都发生在确确实实的更新事件之后,都是有意义的。

2、实时。事件发生后的第一时间即可触发通知操作。

3、可以由Subject确立通知的时间,可以避开一些繁忙时间。

4、可以表达出不同事件发生的先后顺序。


“拉”的好处包括:

1、如果观察者众多,Subject来维护订阅者的列表,可能困难,或者臃肿,把订阅关系解脱到Observer去完成。

2、Observer可以不理会它不关心的变更事件,只需要去获取自己感兴趣的事件即可。

3、Observer可以自行决定获取更新事件的时间。

4、拉的形式可以让Subject更好地控制各个Observer每次查询更新的访问权限。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值