纵观天下,模式之中,Java世界里的观察者模式

一个程序猿的生活感怀

  人活越大,对于世界的认识越简单,越与自己年轻时候的中老年人,以及前人对于某些方面的认识,能够几近达成共识。或许,万象不离其宗,世界虽然千变万化,变的只是表象,本质终难改变!世界遵循着这个模式漫漫千年亘古运行且将永续!

终会浮华散尽,终会返璞归真。


谈谈抽象的观察者模式概念

《JAVA与模式》一书中开头是这样描述观察者(Observer)模式的:

  观察者模式是对象的行为模式,又叫发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听器(Source/Listener)模式或从属者(Dependents)模式。

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

 

抽象观察者模式实际应用画像

  我们大多有过邮件订阅和RSS订阅的经历,当我们浏览一些博客或wiki时,经常会看到RSS图标,当你订阅了该文章,如果后续有更新,会及时通知你。专业一点来讲:当一个对象变化时,其它依赖该对象的对象都会收到通知,并且随着变化!对象之间是一种一对多的关系。

 

坚持不懈,老习惯,用一个实例看看观察者模式

虽然我是个写代码的,但是假设我是一个名扬天下的专栏作家,然后我有人山人海数不清的总值很多很多的订阅读者,他们都急不可耐的想第一时间读到我更新的文章,如何速度最快呢?当然得借助计算机的速度,当然需要借助一下观察者模式啦!

抽象主题(Subject)角色:提供一个接口,可以增删观察者对象,抽象主题角色又叫做抽象被观察者(Observable)角色。

public interface ReaderFans {
	public void update(String newarticle);
}

具体主题(ConcreteSubject)角色:在具体主题的内部状态改变时,给所有登记过的观察者发出通知,具体主题角色又叫做具体被观察者(Concrete Observable)角色。

public class Myreaderfans1 implements ReaderFans {

	public void update(String newarticle) {
		System.out.println("粉丝1号收到了文章更新了");
	}

}

public class Myreaderfans2 implements ReaderFans {

	public void update(String newarticle) {
		System.out.println("粉丝2号收到了文章更新了");
	}

}

抽象观察者(Observer)角色:为所有的具体观察者定义一个接口,在得到主题的通知时更新自己,这个接口叫做更新接口。

public abstract class Writer {
	List<ReaderFans> fans = new ArrayList<ReaderFans>();

	// 增加读者粉丝的方法
	public void addFans(ReaderFans fan) {
		fans.add(fan);
	}

	// 删除读者粉丝的方法
	public void deleteFans(ReaderFans fan) {
		fans.remove(fan);
	}

	// 通知订阅读者的方法
	public void notifyAllMyReaderFans(String newarticle) {
		for (ReaderFans fan : fans) {
			fan.update(newarticle);
		}
	}

}

具体观察者(ConcreteObserver)角色:实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态相协调。 

public class GreatWriterOfMe extends Writer {

	private String newarticle;

	public String getNewarticle() {
		return newarticle;
	}

	public void renew(String newarticle) {
		this.newarticle = newarticle;
		notifyAllMyReaderFans(newarticle);
	}

}

深入、深入、深入,观察者模式的深入:推模型和拉模型

推模型

  主题对象向观察者推送主题的详细信息,不管观察者是否需要,推送的信息通常是主题对象的全部或部分数据。

拉模型

主题对象在通知观察者的时候,只传递少量信息。如果观察者需要更具体的信息,由观察者主动到主题对象中获取,相当于是观察者从主题对象中拉数据。

 

坚持不懈,老习惯,用一个实例看一看拉模型观察者模式:

抽象观察者类

public interface ReaderFans {
	public void update(Writer writer);
}

具体观察者类

public class Myreaderfans1 implements ReaderFans {
	private String newarticle;

	public void update(Writer writer) {
		newarticle = ((GreatWriterOfMe) writer).getNewarticle();
		System.out.println("粉丝1号收到了文章更新了");
	}

}
public class Myreaderfans2 implements ReaderFans {
	private String newarticle;

	public void update(Writer writer) {
		newarticle = ((GreatWriterOfMe) writer).getNewarticle();
		System.out.println("粉丝2号收到了文章更新了");
	}

}

抽象主题者类

public abstract class Writer {
	List<ReaderFans> fans = new ArrayList<ReaderFans>();

	// 增加读者粉丝的方法
	public void addFans(ReaderFans fan) {
		fans.add(fan);
	}

	// 删除读者粉丝的方法
	public void deleteFans(ReaderFans fan) {
		fans.remove(fan);
	}

	// 通知订阅读者的方法
	public void notifyAllMyReaderFans() {
		for (ReaderFans fan : fans) {
			fan.update(this);
		}
	}

}

具体主题者类

public class GreatWriterOfMe extends Writer {

	private String newarticle;
        //给所有订阅读者通知的方法
	public String getNewarticle() {
		return newarticle;
	}

	public void renew(String newarticle) {
		this.newarticle = newarticle;
		notifyAllMyReaderFans();
	}

}

JAVA提供的对观察者模式的支持

在JAVA语言的java.util库里面,提供了一个Observable类以及一个Observer接口,构成JAVA语言对观察者模式的支持。

Observer接口只定义了一个方法,即update()方法,当被观察者对象的状态发生变化时,被观察者对象的notifyObservers()方法就会调用这一方法。

public interface Observer {

    void update(Observable o, Object arg);

}

被观察者类都是java.util.Observable类的子类,Observable提供公开的方法支持观察者对象,重要方法有两个:一个是setChanged(),另一个是notifyObservers()。第一方法setChanged()被调用之后会设置一个内部标记变量,代表被观察者对象的状态发生了变化。第二个是notifyObservers(),这个方法被调用时,会调用所有登记过的观察者对象的update()方法,使这些观察者对象可以更新自己。


扯淡能扯三天,但扯多终会累,咱们下回分解,那就猛然结尾!!!!!!

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值