设计模式 - observer
简单来讲,就是observer依赖于subject,当subject发生变化时,observer得到通知,并将状态与subject同步,常来用于维护对象间状态的一致性。
observer的工作过程大体如下:
注册:
observer将自身注册到subject中,subject中通常保有一份注册的observer列表。
通知:
当subject发生变化时,会遍历自身保有的观察者列表,并调用observer的update方法,更新其自身状态
销毁:
当注销时,销毁subject中的observer即可。
缺陷:
a. 观察者模式中的observer并不知道对方的存在,因此在subject中状态改变后,难以预料对其他observer的影响。
b. 当删除subject中,需要注意去除observer中的悬挂引用。通常的解决方案是在删除subject时,通知observer进行处理。
改进:
观察者模式的核心是依赖关系,上面的例子中,observer和subject的关系尤其自身来保存,但当遇到复杂的依赖和注册关系,以及不同的通知机制时,可以通过抽象出changeManager来减少observer反应其变更的工足量。
如:如果一个操作涉及到几个相互依赖的目标进行改动,就必须保证在所有目标都已经更新完毕后,才一次性通知其observer,而非每个subject分别通知。
代码示例:
package com.inspur.jiyq.designpattern.observer; import com.inspur.jiyq.designpattern.observer.impl.ConcreteObserver; import com.inspur.jiyq.designpattern.observer.impl.ConcreteSubject; public class ObserverMain { public static void main(String[] args) { Subject subject = new ConcreteSubject(); //observer注册到suject中 ConcreteObserver observer1 = new ConcreteObserver(subject); ConcreteObserver observer2 = new ConcreteObserver(subject); subject.notice(); } }
package com.inspur.jiyq.designpattern.observer; public interface Subject { /** * 注册observer */ public void attach(Observer observer); /** * 注销 observer */ public void detach(Observer observer); /** * 通知observer */ public void notice(); /** * 获取内部状态 * @return * 内部状态 */ public String getState(); /** * 设置内部状态 * * @param innerState * 内部状态 */ public void setState(String innerState); }
package com.inspur.jiyq.designpattern.observer; public interface Observer { public void update(Subject subject); }
package com.inspur.jiyq.designpattern.observer.impl; import java.util.ArrayList; import java.util.List; import com.inspur.jiyq.designpattern.observer.Observer; import com.inspur.jiyq.designpattern.observer.Subject; public class ConcreteSubject implements Subject { private List<Observer> observers = new ArrayList<Observer>(); private String innerState = null; @Override public void attach(Observer observer) { this.observers.add(observer); } @Override public void detach(Observer observer) { this.observers.remove(observer); } @Override public void notice() { for (Observer observer : observers) { // 将自身状态更新至observer,保证状态一致性 observer.update(this); } } /** * 返回自身状态 */ @Override public String getState() { return innerState; } /** * 返回自身状态 */ public void setState(String innerState) { this.innerState = innerState; } }
package com.inspur.jiyq.designpattern.observer.impl; import com.inspur.jiyq.designpattern.observer.Observer; import com.inspur.jiyq.designpattern.observer.Subject; public class ConcreteObserver implements Observer { Subject subject; public ConcreteObserver(Subject subject) { this.subject= subject; subject.attach(this);; } @Override public void update(Subject subject) { System.out.println("I got a new state."); } }