设计模式学习之观察者模式--3

定义

在对象之间定义一对多的依赖,这样一来,当一个对象改变状态,依赖它的对象都会收到通知,并自动更新。

认识观察者模式

出版者+订阅者=观察者模式

如果你了解报纸的订阅是怎么回事,其实就知道观察者模式是怎么回
事,只是名称不太一样:出版者改称为“主题”(Subject),订阅者改称
为“观察者”(Observer)。

松耦合

观察者模式提供了一种对象设计,让主题和观察者之间松耦合。

为什么呢?关于观察者的一切,主题只知道观察者实现了某个接口(也就是Observer接口)。
主题不需要知道观察者的具体类是谁、做了些什么或其他任何细节。
任何时候我们都可以增加新的观察者。因为主题唯一依赖的东西是一个实现Observer接口的对象列表,所以我们可以随时增加观察者。事实上,在运行时我们可以用新的观察者取代现有的观察者,主题不会受到任何影响。同样的,也可以在任何时候删除某些观察者。
有新类型的观察者出现时,主题的代码不需要修改。假如我们有个新的具体类需要当观察者,我们不需要为了兼容新类型而修改主题的代码,所有要做的就是在新的类里实现此观察者接口,然后注册为观察者即可。主题不在乎别的,它只会发送通知给所有实现了观察者接口的对象。
我们可以独立地复用主题或观察者。如果我们在其他地方需要使用主题或观察者,可以轻易地复用,因为二者并非紧耦合。
改变主题或观察者其中一方,并不会影响另一方。因为两者是松耦合的,所以只要他们之间的接口仍被遵守,我们就可以自由地改变他们。

主题接口

public interface Subject {
	//注册观察者
	public void registerObserver(Observer o);
	//移除观察者
	public void removeObserver(Observer o);
	//通知观察者
	public void notifyObservers();
}

观察者接口

public interface Observer {
	void update(float price);
}

书店实现了主题接口

public class Bookstore implements Subject{
	List<Observer> observers;
	private float price;
	public Bookstore(){
		observers = new ArrayList<>();
	}
	@Override
	public void registerObserver(Observer o) {
		observers.add(o);
	}
	@Override
	public void removeObserver(Observer o) {
		if(observers.indexOf(o)>=0){
			observers.remove(o);
		}
	}
	@Override
	public void notifyObservers() {
		observers.forEach(o->o.update(price));
	}
	//当书本价格变动时通知观察者
	public void priceChanged() {
		notifyObservers();
	}
	//模拟书本价格的更新
	public void setMeasurements(float price) {
		this.price = price;
		priceChanged();
	}
}

我们可以把观察者,也就是观察着书店的书价格的人作为一个接口

public interface Person {
	void display();
}

具体的观察者

public class SuQin implements Observer,Person{
	private Subject bookstore;
	private float price;
	//把自己注册为书店价格变动的观察者
	public SuQin(Subject subject){
		this.bookstore=subject;
		subject.registerObserver(this);
	}
	@Override
	public void update(float price) {
		this.price=price;
	}
	@Override
	public void display(){
		System.out.println("苏秦得到了通知,书的价格变动为:"+this.price+"元");
	}
}


public class ZhangYi implements Observer,Person{
	Subject subject;
	private float price;
	public ZhangYi(Subject subject){
		this.subject = subject;
		subject.registerObserver(this);
	}
	@Override
	public void update(float price) {
		this.price=price;
	}
	@Override
	public void display(){
		System.out.println("张仪得到了通知,书的价格变动为:"+this.price+"元");
	}
}

测试一下

public class App {
	public static void main(String[] args) {
		Bookstore bookstore = new Bookstore();
		SuQin suQin = new SuQin(bookstore);
		ZhangYi zhangYi = new ZhangYi(bookstore);
		bookstore.setMeasurements(80);
		suQin.display();
		zhangYi.display();
	}
}

当书店书的价格变动时,苏秦和张仪两个人都会得到价格变动的通知。

实际上java API已经有了内置的观察者模式。java.util包(package)内包含最基本的Observer接口与Observable类,这和我们的Subject接口与Observer接口很相似。但是java.util.Observer是一个类而非一个接口,如果某类想同时具有Observable类和另一个超类的行为,就会陷入两难,毕竟Java不支持多重继承。这限制了Observable的复用潜力。

要点

  • 观察者模式定义了对象之间一对多的关系。
  • 主题(也就是被观察者)用一个接口更新观察者。
  • 观察者与被观察者之间用松耦合的方式结合。被观察者不知道观察者的细节,只知道观察者都实现了同一个观察者接口。
  • java有多种观察者模式的实现,包括通用的java.util.Observerable。

猜你喜欢

转载自blog.csdn.net/administratorJWT/article/details/85264137