观察者模式

观察者模式
定义:
    定义对象间一种一对多的依赖关系,当一个对象的状态发生改变时,
所有依赖它的对象都会得到通知并且自动更新
观察者模式6大方面:
    1,目标与观察者之间的关系
    2,单向依赖
    3,命令建议
   第一 目标接口的定义,建议在名称后面跟Subject
第二 观察者接口的定义,建议在名称后面跟Observer
第三 观察者接口的更新方法,建议名称为update
    4,触发通知的时机
    5,观察者模式的调用顺序示意图
    6,通知的顺序
观察者模式两种模式
    1.推模型:目标对象主动向观察者推送目标的详细信息 ; 推送的信息通常是目标信息的全部或部分信息
    2.拉模型:目标对象在通知观察者的时候,只传递少量信息 ;
如果观察者需要更具体的信息,由观察者主动到目标对象中获取,相当于是观察者从目标对象中拉数据;
一般这种模型的实现中,会把目标对象自身通过update方法传递给观察者。

比较:
推模型是假定目标对象知道观察着需要的数据
拉模型是目标对象不知道观察着具体需要什么数据,因此把自身传给观察者,由观察者来取值

java.util包中Observable类可以实现目标类
接口Observer定义了update()方法 可以实现观察者类


观察者模式的优点:
(1)观察者模式实现了观察者和目标之间的抽象耦合
(2)观察者模式实现了动态联动
(2)观察者模式支持广播通信
观察者模式的缺点:
    可能会引起无谓的操作
建议在以下情况下使用观察者模式:触发联动
(1)当一个抽象模型有两个方面,其中一个方面的操作依赖于另一个方面的状态变化
(2)如果在更改一个对象的时候,需要同时连带改变其他的对象,而且不知道究竟应该 有多少对象需要被连带改变

(3) 当一个对象必须通知其他的对象,但是你又希望这个对象和其他的被通知的对象是松散耦合的


区别对待观察者的场景问题:即不同的观察者按照需求收到不同的信息

import java.util.ArrayList;
import java.util.List;

public abstract class WeatherSubject {
	//用来保存注册的观察者对象
	public List<Observer> observers=new ArrayList<Observer>();
	//attach detach nnofiyObservers
	public void attach(Observer observer){
		observers.add(observer);
	}
	public void detach(Observer observer){
		observers.remove(observer);
	}
	protected abstract void notifyObserver();
}


//定义一个更新的接口方法给那些目标发生变化的
public interface Observer {
	//更新的接口
	public void update(WeatherSubject subject);
	
	//设置观察者名称
	public void setObserverName(String observerName);
	//取得观察者名称
	public String getObserverName();
}

public class ConcreteWeatherSubject extends WeatherSubject {
	//晴天,下雨,下雪
	//目标对象的状态
	private String weatherContent;
	
	@Override
	protected void notifyObserver() {
		//循环所有注册的观察者
		for(Observer ob:observers){
			//规则是
			//女朋友需要下雨通知,老妈需要下雨下雪通知
			
			//如果是晴天,都不通知
			
			//如果是下雨
			if("下雨".equals(this.getWeatherContent())){
				if("女朋友".equals(ob.getObserverName()))
					ob.update(this);
				if("老妈".equals(ob.getObserverName()))
					ob.update(this);
			}
			//如果是下雪
			if("下雪".equals(this.getWeatherContent())){
				if("老妈".equals(ob.getObserverName()))
					ob.update(this);
			}
		}
	}

public class ConcreteObserver implements Observer {

	//观察者的名称
	private String observerName;
	//天气情况的内容
	private String weatherContent;
	//提醒的内容
	private String remindThing;
	public void update(WeatherSubject subject) {
		weatherContent=((ConcreteWeatherSubject)subject).getWeatherContent();
		System.out.println(observerName+"收到了"+weatherContent+","+remindThing);
	}
	public void setObserverName(String observerName){
		this.observerName=observerName;
	}
	//取得观察者名称
	public String getObserverName(){
		return observerName;
	}
	public String getWeatherContent() {
		return weatherContent;
	}
	public void setWeatherContent(String weatherContent) {
		this.weatherContent = weatherContent;
	}
	public String getRemindThing() {
		return remindThing;
	}
	public void setRemindThing(String remindThing) {
		this.remindThing = remindThing;
	}
}

public class Client {

	public static void main(String[] args) {
		//创建目标
		ConcreteWeatherSubject ws=new ConcreteWeatherSubject();
		
		//创建观察者
		ConcreteObserver girl=new ConcreteObserver();
		girl.setObserverName("女朋友");
		girl.setRemindThing("下雨了,在家吧");
		
		ConcreteObserver mum=new ConcreteObserver();
		mum.setObserverName("老妈");
		mum.setRemindThing("我都不出门");
		
		//注册观察者
		ws.attach(girl);
		ws.attach(mum);
		//发布天气
		ws.setWeatherContent("晴天");
	}

}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值