大话设计模式java版--观察者模式


我们先思考一个问题。如果一个网站设置了天气显示的功能,而且天气显示的功能我们都是获取官网给的数据显示的。而官网的数据是不定期更新的。

我们有两种设计方案:

第一种

在网站上设置线程,线程每隔1分钟去读取官网数据,然后跟自己网站数据做比较,如果是改变了就更新。

这种设计方式看上去很合理。但是我们试想这样做的话,如果我们要获取比较频繁的数据的话,但数据又不知道什么时候会更新。这就引出了我们的第二种方案--


观察者模式也叫 发布-订阅

第二种

观察者模式当然也是遵循面向接口编程的,原理也是,我们可以订阅官网的天气数据,如果天气数据发生变化,官网会发送消息告诉自己网站“我们官网的数据更新了”,我们自己的网站接受到这条消息,自然会调用更新方法。


先看一个场景:

老板要通知同事们做事

分析:是老板作为通知类,而同事做为观察者类。

于是我们有

Subject.java接口

package com.jing.observer;
/**
 * 抽象通知者类
 * @author Administrator
 *
 */
public interface Subject {
	public void attach(Observer observer);
	public void detach(Observer observer);
	public void myNotify();
}

接着是观察者接口

package com.jing.observer;

public interface Observer {
	//抽象观察者类
	public void updata();
}


接着老板类实现通知者接口

SubjectBoss.java

package com.jing.observer;

import java.util.ArrayList;
import java.util.List;
/**
 * 具体通知者类
 * @author Administrator
 *
 */
public class SubjectBoss implements Subject{
	List<Observer> observers = new ArrayList<Observer>();
	@Override
	public void attach(Observer observer) {
		observers.add(observer);
	}

	@Override
	public void detach(Observer observer) {
		observers.remove(observer);
	}

	@Override
	public void myNotify() {
		for(Observer oberver :observers){
			oberver.updata();
		}
	}



}


接着实现观察者 就是同事类

ObserverSeeStock.java

package com.jing.observer;

public class ObserverSeeStock implements Observer{

	@Override
	public void updata() {
		System.out.println("ObserverSeeStock 更新");
	}

}


之后是main函数

package com.jing.observer;

public class Main {
	public static void main(String[] args) {
		//没有加委托的 观察者模式..
		Subject boss = new SubjectBoss();//大老板  通知类
		
		Observer seeStock = new ObserverSeeStock();//同事一 看股票 具体观察者1
		Observer seeNba = new ObserverSeeNba();//同事二 看Nba 具体观察者2
		Observer seeMovie = new ObserverSeeMovie();//这种是违背原则的。。。
		Observer seeSky = new MyProxy();//利用代理模式 就是为了不修改ObserverSeeSky这个类
		
		boss.attach(seeStock);//添加观察者
		boss.attach(seeNba);//添加观察者
		boss.attach(seeMovie);
		boss.attach(seeSky);
		
		
		boss.myNotify();//通知更新
	}
}

ObserverSeeStock订阅了老板的通知,所以当老板用myNotify会接收到更新通知。


==========================================================

至此这就是观察者模式了。

========================================================

但是我们来分析下。如果我们要用有新的观察者时,我们就要实现Observer接口,然后实现updata方法。

package com.jing.observer;

public class ObserverSeeSky {
	public void seeSky(){
		System.out.println("sky updata");
	}
}

这里我们来了个seeSky()方法我们是不是要修改这个类实现Observer接口

package com.jing.observer;

public class ObserverSeeMovie implements Observer{
	//通过实现接口通知更新 ,但是这样的做法违背了开放封闭原则。
	
	public void seeMovie(){
		System.out.println("看电影 更新");
	}
	
	@Override
	public void updata() {
		seeMovie();
		
	}

}

这样做我们可以看到这是违背的开放-封闭原则的



于是我们就有了代理模式+观察者模式的做法了

package com.jing.observer;

public class MyProxy implements Observer{
	//代理ObserverSeeSky
	private ObserverSeeSky observer = new ObserverSeeSky();

	@Override
	public void updata() {
		observer.seeSky();
	}
	
}

这个MyProxy是代理了OBserverSeeSky的,而OBserverSeeSky的方法是完全没改动的。


这也是个人的见解了,有不对的地方欢迎大家来讨论。





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值