十九、观察者模式Observer(行为型)

观察者模式定义了对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知,并被自动更新。

将一个系统分割成一系列相互协作的类有一种常见的副作用,需要维护相关对象间的一致性,我们不希望为了维护一致性而使各种类紧密耦合,这样会降低它们的可重用性。观察者模式可以描述一个对象改变时,与之相关的对象状态也可以被动更新。在观察者模式中,一个Observer可以订阅任意数量的Subject,一旦Subject的状态发生改变的时候,所有的观察者都会得到通知。

观察者适用于,一个抽象模型有两个方面,其中一个方面依赖于另一个方面,或者当一个对象改变时需要同时改变其他对象,但是这些对象是运行时加入的。


public interface Observer {
	public void update(Subject subject);
}
public interface Subject {

	public void attach(Observer observer);

	public void detach(Observer observer);

	public void observerNotify();

}
public class ConcreteObserver implements Observer {

	private Subject subject = null;

	public ConcreteObserver(Subject subject) {
		this.subject = subject;
		this.subject.attach(this);
	}

	@Override
	public void update(Subject subject) {
		if (this.subject == subject) {
			System.out.println("Update myself(" + this + ") and do other things!");
		}
	}
}
public class ConcreteSubject implements Subject {
	private Set<Observer> observers = null;

	public ConcreteSubject() {
		observers = new HashSet<>();
	}

	public void attach(Observer observer) {
		observers.add(observer);
	}

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

	public void observerNotify() {
		for (Observer o : observers) {
			o.update(this);
		}
	}
}
public class Client {
	@Test
	public void test() {
		// create a subject
		Subject subject = new ConcreteSubject();
		// create two observers that subscribe the subject
		@SuppressWarnings("unused")
		Observer observer1 = new ConcreteObserver(subject);
		@SuppressWarnings("unused")
		Observer observer2 = new ConcreteObserver(subject);
		// subject state changed and notify all these observers
		subject.observerNotify();
	}
}

Subject可以被订阅,同时Subject中也会存储所有订阅了自己的Observer的集合,当Observer订阅了Subject后,只要Subject的状态改变了,就可以调用notify方法来告知所有订阅了它的Observer,这样所有Observer都会得到相应通知。

此外,在Java中是默认支持观察者模式的,它是通过Observable类和Observer接口实现了观察者模式。Observer对象是观察者,Observable对象是被观察者。当观察者事件发生时需要标记Observable的状态setChanged();把自己标记为改变的状态,然后通知所有的观察者自己的状态已经改变。

public class SubjectJava extends Observable{
	private String state;

	public String getState() {
		return state;
	}

	public void setState(String state) {
		this.state = state;
		setChanged();//Marks this Observable object as having been changed
		notifyObservers();//notify all Observers
	}
}
public class ObserverJava implements java.util.Observer{
	
	@Override
	public void update(Observable o, Object arg) {
		SubjectJava suject = (SubjectJava) o;
		System.out.println(suject.getState());
	}
}
public class Client {
	@Test
	public void testJava() {
		SubjectJava subject = new SubjectJava();
		ObserverJava observer1 = new ObserverJava();
		subject.addObserver(observer1);

		subject.setState("A");
		subject.setState("B");
		subject.setState("C");
	}
}

Java中的观察者模式比手工实现要方便很多,而且从源码上看很多Observable的方法都是同步的,故Observable可以在多线程下使用。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值