观察者模式

观察者模式(发布-订阅模式)

定义

定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。

特点

将一个系统分割成一系列相互协作的类有一个很不好的副作用,那就是需要维护相关对象间的一致性。我们不希望为了维持一致性而使各类紧密耦合,这样会给维护、扩展和重用都带来不便。
当一个对象的改变需要同时改变其他对象时,而且他不知道具体有多少对象需要改变时,应该考虑使用观察者模式。总的来说,观察者模式是在解除耦合,让耦合的双方都依赖于抽象,而不是依赖的具体,从而使得各自的变化都不会影响另一边的变化。

UML图

在这里插入图片描述

用例

抽象通知者

interface Subject{
	void attach(Observer observer);
	void detach(Observer observer);
	void notify();
	public String getSubjectState();
	public String setSubjectState();
}

具体通知者:可能是前台,可能是老板,它们各自有方法,但对于抽象通知者来说都一样,所以它们都实现这个接口。

class Boss implements Subject{
	//同事列表
	private List<Observer> observers = new List<Observer>();
	private String action;
	//增加
	public void attach(Observer observer){
		observers.add(observer);
	}
	//减少
	public void detach(Observer observer){
		observers.remove(observer);
	}
	//通知
	public void notify(){
		for(v : observers)
		 	v.uodate();
	}
	//老板状态
	public String getSubjectState(){
		return action;
	};
	public String setSubjectState(String action){
		this.action = action;
	}; 
}

抽象观察者

abstract class Observer{
	protected String name;
	protected Subject sub;
	public Observer(String name, Subject sub){
		this.name = name;
		this.sub = sub;
	}
	public abstract void update();
}

具体观察者

class StockObserver extends Observer{
	@Override
	public void update(){
		System.out.printlv(sub.getSubjectState + name + "老板来了,关闭股市行情,继续工作。");
	}
}

客户端代码

Boss huahansan = new Boss();
//看股票的同事
StockObserver so = new StockObserver ("小明",huhansan);
//看NBA的同事
NBAObserver no = new NBAObserver ("小红",huhansan);
huhansan.attach(so);
huhansan.attach(no);
huhansan.setSubjectState("我胡汉三又回来了!");
huhansan.notify();

此例的不足

  1. 抽象通知者依赖抽象观察者,如果没有抽象观察者这样的接口,通知者就无法通知了。
  2. 每个具体观察者不一定都要用notify方法。

用例(改进)

事件委托实现:
委托就是一种引用方法的类型。一旦为委托分配了方法,委托将与该方法具有完全相同行为。委托方法的使用可以像其他任何方法一样,具有参数和返回值。委托可以看做函数的抽象,是函数的类,委托的实例代表一个具体的函数。
一个委托可以搭载多个方法,所有方法被依次唤起,重要的是委托对象搭载的方法并不需要来自同一个类。但是委托对象搭载的所有方法必须具有相同的原形和形式,即拥有相同的参数列表和返回值类型。
去掉抽象观察类,为具体观察者类添加各自合适的方法。

class StockObserver{
	protected String name;
	protected Subject sub;
	public StockObserver(String name, Subject sub){
		this.name = name;
		this.sub = sub;
	}
	//关闭股市行情
	public void closeStockMarket(){
		System.out.printlv(sub.getSubjectState + name + "老板来了,关闭股市行情,继续工作。");
	}
}

class NBAObserver{
	protected String name;
	protected Subject sub;
	public NBAObserver(String name, Subject sub){
		this.name = name;
		this.sub = sub;
	}
	//关闭NBA直播
	public void closeNBADirectSeeding(){
		System.out.printlv(sub.getSubjectState + name + "老板来了,关闭NBA直播,继续工作。");
	}
}

抽象通知者:由于不想依赖于抽象观察者,所以不需要“增加”和“减少”方法。

interface Subject{
	void notify();
	public String getSubjectState();
	public String setSubjectState();
}

具体通知类:声明委托完成通知

public delegate void EventHandler();//无参数,无返回值

//老板类 前台秘书类类似,略
class Boss extends Subject{
	private String action;
	//声明一个事件event,类型为委托
	public event EventHandler update;
	
	public void notify(){
		update();
	}
	
	//老板状态
	public String getSubjectState(){
		return action;
	};
	public String setSubjectState(String action){
		this.action = action;
	}; 
}

客户端:决定通知谁

Boss huahansan = new Boss();
//看股票的同事
StockObserver so = new StockObserver ("小明",huhansan);
//看NBA的同事
NBAObserver no = new NBAObserver ("小红",huhansan);

//老板的状态更新导致新增通知事件给看股票的或者看NBA直播的
huhansan.update += new EventHandler(so.closeStockMarket());
huhansan.update += new EventHandler(no.closeNBADirectSeeding());
huhansan.setSubjectState("我胡汉三又回来了!");
huhansan.notify();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值