观察者模式
观察者模式又叫发布-订阅模式
观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使他们能够自动更新自己。
观察者模式特点
将一个系统分割成一系列相互协作的类有一个很不好的副作用,那就是需要维护相关对象间的一致性。我们不希望为了维持一致性而使各类紧密耦合,这样会给维护,拓展和重用都带来不便。
一个对象的改变需要同时改变其他对象,而且它不知道具体有多少对象有待改变时,应该考虑使用观察者模式。
一个抽象模型有两方面,其中一方面依赖于另一方面,这时用观察者模式可以将这两者封装在独立的对象中使它们各自独立的改变和复用。
观察者模式所做的工作其实就是在解除耦合,让耦合的双方都依赖于抽象,而不是依赖于具体。从而使得各自的变化都不会影响另一边的变化。
14. 观察者模式
/**
*
* 抽象被观察者接口
* 声明了添加,删除,通知观察者方法
*/
public interface Observerable {
void registerObserver(Observer observer);
void removeObserver(Observer observer);
void notifyObserver();
}
/**
*
* 抽象观察者接口
* 定义了一个update方法,当被观察者调用notifyObserver方法时,观察者的update方法会被回调
*/
public interface Observer {
void update(String message);
}
/**
*
* 具体的被观察者
*/
public class WechatServer implements Observerable {
// 注意这个list集合的泛型参数为Observer接口,设计原则:面向接口编程而不是面向实现编程
private List<Observer> list;
private String message;
public WechatServer() {
list = new ArrayList<>();
}
@Override
public void registerObserver(Observer observer) {
list.add(observer);
}
@Override
public void removeObserver(Observer observer) {
if (!list.isEmpty()) {
list.remove(observer);
}
}
@Override
public void notifyObserver() {
for (int i = 0; i < list.size(); i++) {
Observer observer = list.get(i);
observer.update(message);
}
}
public void setInformation(String s) {
this.message = s;
// 消息更新,通知所有观察者
notifyObserver();
}
}
/**
*
* 具体的观察者
*/
public class User implements Observer {
private String name;
private String message;
public User(String name) {
this.name = name;
}
@Override
public void update(String message) {
this.message = message;
read();
}
public void read() {
Log.d("WM",name + "收到推送消息: " + message);
}
}
测试方法
public void test() {
WechatServer server = new WechatServer();
User user1 = new User("张三");
User user2 = new User("李四");
User user3 = new User("王五");
server.registerObserver(user1);
server.registerObserver(user2);
server.registerObserver(user3);
server.setInformation("PHP是世界上最好的语言!");
Log.d("WM","---------------------------");
server.removeObserver(user2);
server.setInformation("Java是世界上最好的语言!");
}