设计模式之观察者模式笔记
- 说明
- Observer(观察者)
- 目录
- 观察者模式示例类图
- 抽象主题角色类
- 抽象观察者类
- 具体主题角色类
- 具体的观察者角色类
- 测试类
说明
记录下学习设计模式-观察者模式的写法。JDK使用版本为1.8版本。
Observer(观察者)
意图:定义对象间的一种一对多的依赖关系,当一个对象的状态发送改变时,所有依赖于它的对象都得到通知并被自动更新。
结构:
其中:
- Subject(目标)知道它的观察者,可以有任意多个观察者观察同一个目标;提供注册和删除观察者对象的接口。
- Observer(观察者)为那些在目标发送改变时需获得通知的对象定义一个更新接口。
- ConcreteSubject(具体目标)将有关状态存入各ConcreteObserver对象;当它的状态发生改变时,向它的各个观察者发出通知。
- ConcreteObserver(具体观察者)维护一个指向ConcreteSubject对象的引用;存储有关状态,这些状态应与目标的状态保持一致;实现Observer的更新接口,以使自身状态与目标的状态保持一致。
适用性:
- 当一个抽象模型有两个方面,其中一个方面依赖于另一个方面,将这两者封装在独立的对象中以使它们可以各自独立地改变和复用。
- 当对一个对象的改变需要同时改变其他对象,而不知道具体有多少对象有待改变时。
- 当一个对象必须通知其他对象,而它又不能假定其他对象是谁,即不希望这些对象是紧耦合的。
目录
观察者模式示例类图
以该UML类图实现观察者模式示例。
抽象主题角色类
package com.example.deesign_patterns.observer;
//抽象主题角色类
public interface Subject {
//添加订阅者(添加观察者对象)
void attach(Observer observer);
//删除订阅者
void detach(Observer observer);
//通知订阅者更新消息
void notify(String message);
}
抽象观察者类
package com.example.deesign_patterns.observer;
//抽象观察者类
public interface Observer {
void update(String message);
}
具体主题角色类
package com.example.deesign_patterns.observer;
import java.util.ArrayList;
import java.util.List;
//具体主题角色类
public class SubscriptionSubject implements Subject{
//定义一个集合用来存储多个观察者对象
private List<Observer> weiXinUserList=new ArrayList<Observer>();
@Override
public void attach(Observer observer) {
weiXinUserList.add(observer);
}
@Override
public void detach(Observer observer) {
weiXinUserList.remove(observer);
}
@Override
public void notify(String message) {
//遍历集合
for(Observer observer:weiXinUserList){
//调用观察者对象中的update方法
observer.update(message);
}
}
}
具体的观察者角色类
package com.example.deesign_patterns.observer;
//具体的观察者角色类
public class WeiXinUser implements Observer{
private String name;
public WeiXinUser(String name) {
this.name = name;
}
@Override
public void update(String message) {
System.out.println(name+"-"+message);
}
}
测试类
package com.example.deesign_patterns.observer;
//测试类
public class Client {
public static void main(String[] args) {
//创建公众号对象
SubscriptionSubject subject=new SubscriptionSubject();
//订阅公众号
subject.attach(new WeiXinUser("张三"));
subject.attach(new WeiXinUser("李四"));
subject.attach(new WeiXinUser("王五"));
//公众号更新,发出消息给订阅者(观察者对象)
subject.notify("微信内容的专栏更新了!");
}
}
好处:
- 降低了目标与观察者之间的耦合关系,两者之间是抽象耦合关系。
- 被观察者发送通知,所有注册的观察者都会受到信息【可以实现广播机制】。
缺点:
- 如果观察者非常多的话,那么所有的观察者收到被观察者发送的通知会耗时。
- 如果被观察者有循环依赖的话,那么被观察者发送通知会使观察者循坏调用,会导致系统崩溃。