1.定义
定义对象间的一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。
2.解决的问题 现状:有时我们会将一个系统分割成一系列相互协作的类,但是这样会有一个副作用---需要维护相关对象间的一致性。这样的话我们为了维持一致性而使得各个类之间紧密耦合,导致可重用性的降低,会给维护、扩展和重用都带来不便。观察者就是解决这类的耦合关系的。 观察者模式使得任意树木的观察者不必知道彼此的存在,且主题发生变化时都可以得到主题的通知,而同步改变状态。是一种松散耦合,且有更好的可重用性。 3.模式的组成结构 抽象主题(Subject):它把所有观察者对象的引用保存到一个集合里,每个主题都可以有任何数量的观察者。抽象主题提供一个接口,可以增加和删除观察者对象。具体主题(ConcreteSubject):将有关状态存入具体观察者对象;在具体主题内部状态改变时,给所有登记过的观察者发出通知。
抽象观察者(Observer):为所有的具体观察者定义一个接口,在得到主题通知时更新自己。 具体观察者(ConcreteObserver):实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题状态协调。 4.模式的类图
由于自己还不会画类图,就网上找了一张
5.具体实现代码 5.1.IPrettyGirl.java
package com.example.design.observer;5.2.IObserver.java
/*
* 抽象主题角色
* 类型是接口或者抽象类
*/
public interface IPrettyGirl {
public void addObservers(IObserver observers);//添加观察者
public void deleteObservers(IObserver observers);//删除观察者
public void notifyAllObservers(String msg);//通知所有的观察者
}
//public abstract class IPrettyGirl{
//public abstract void addObservers(IObserver observers);//添加观察者
//
//public abstract void deleteObservers(IObserver observers);//删除观察者
//
//public abstract void notifyAllObservers(String msg);//通知所有的观察者
//
//}
package com.example.design.observer;5.3 Angelababy.java
/**
*
* 抽象观察者
*
*/
public interface IObserver {
public void UpdateMsg(String msg);
}
package com.example.design.observer;5.4.Observers.java
import java.util.ArrayList;
import java.util.List;
/*
* 具体主题
* 这里选取众多屌丝追女神的例子
*/
public class Angelababy implements IPrettyGirl {
// 观察者集合
private List<IObserver> mList = new ArrayList<IObserver>();// 注意这里集合的泛型用的是接口类型
public void addObservers(IObserver observers) {
mList.add(observers);
}
@Override
public void deleteObservers(IObserver observers) {
mList.remove(observers);
}
@Override
public void notifyAllObservers(String msg) {
for (IObserver list : mList) {
list.UpdateMsg(msg);
}
}
}
package com.example.design.observer;然后多写几个观察者(屌丝)类,这里就不贴代码了,同4。
/**
*
* 具体观察者
* 屌丝男一
*/
public class Observers implements IObserver {
private String name;
public Observers(String name) {
this.name = name;
}
@Override
public void UpdateMsg(String msg) {
// TODO 自动生成的方法存根
if ("我不开心".equals(msg)) {
System.out.println(name+"说: 多喝热水");
}
}
}
5.5 测试主方法
package com.example.design.observer;5.6.输出结果
/**
* ----观察者模式----
*
*/
public class TestMain {
public static void main(String[] args) {
// TODO 自动生成的方法存根
Observers observers1 = new Observers("王大锤");
Observers2 observers2 = new Observers2("黄晓明");
Observers3 observers3 = new Observers3("郑恺");
Observers4 observers4 = new Observers4("邓超");
Angelababy angelababy = new Angelababy();
// 注册添加观察者
angelababy.addObservers(observers1);
angelababy.addObservers(observers2);
angelababy.addObservers(observers3);
angelababy.addObservers(observers4);
// 发出通知消息
angelababy.notifyAllObservers("我不开心");
//删除观察者
angelababy.deleteObservers(observers1);
System.out.println("---------------------");
angelababy.notifyAllObservers("我不开心");
}
}
王大锤说: 多喝热水
黄晓明说:多喝热水,么么哒
郑恺说:走,带你去看电影
邓超说:走,带你去吃缙云烧饼
---------------------
黄晓明说:多喝热水,么么哒
郑恺说:走,带你去看电影
邓超说:走,带你去吃缙云烧饼
6.模式的总结
6.1 优点
观察者模式解除了主题和具体观察者的耦合,让耦合的双方都依赖于抽象,而不是依赖具体。从而使得各自的变化都不会影响另一边的变化。
6.2 缺点
依赖关系并未完全解除,抽象通知者依旧依赖抽象的观察者。
6.3 适用场景
当一个对象的改变需要给变其它对象时,而且它不知道具体有多少个对象有待改变时。
一个抽象某型有两个方面,当其中一个方面依赖于另一个方面,这时用观察者模式可以将这两者封装在独立的对象中使它们各自独立地改变和复用。
如果上面有什么不妥的地方,欢迎留言指正