1. 观察者模式介绍
观察者模式(Observer Pattern)是一种行为设计模式,它定义了一种一对多的依赖关系,使得多个观察者对象可以监听一个主题对象。当主题对象的状态发生变化时,所有依赖于它的观察者都会收到通知并更新。
**优势:**观察者模式使得对象之间的耦合性降低,主题与观察者之间的关系是松耦合的,有助于提高系统的可维护性和扩展性。
**类比:**可以将观察者模式类比为社交媒体上的关注功能。假设你在某个社交平台上关注了一位博主,当这位博主发布新内容时,你会收到通知。这种机制类似于观察者模式:博主是主题,关注者是观察者,博主发布新内容(状态变化)时,所有关注者都会收到通知(更新)。
关键组成部分:
- 主题(Subject):拥有状态的对象,维护一个观察者列表,并定义方法来添加、删除和通知观察者。
- 观察者(Observer):观察主题对象的状态变化,并在收到通知时进行更新。
- 具体主题(Concrete Subject):实现主题接口,并在状态变化时通知所有观察者。
- 具体观察者(Concrete Observer):实现观察者接口,定义更新方法以响应主题的状态变化。
应用场景:
- GUI事件处理:按钮点击后通知注册的监听器。
- 数据模型与视图同步:当数据变化时,视图自动更新。
- 消息订阅系统:订阅者接收发布者的消息更新。
2. 代码演示
**演示场景:**多位用户(Follower) 关注一位博主(Blog),当博主发了新博客后,其关注者都能收到更新消息。这里的博主属于主题Subject,用户们属于观察者Observer,是一对多的关系。
观察者接口(Observer):
java
public interface Observer {
void update(String message);
}
主题接口(Observer)
java
public interface Subject {
void registerObserver(Observer observer);
void removeObserver(Observer observer);
void notifyObservers();
}
具体主题(Concrete Subject)
java
public class Blog implements Subject {
//维护一个观察者列表
private final List<Observer> observers = new ArrayList<>();
//最新博客信息
private String latestPost;
@Override
public void registerObserver(Observer observer) {
observers.add(observer);
}
@Override
public void removeObserver(Observer observer) {
observers.remove(observer);
}
@Override
public void notifyObservers() {
for (Observer observer : observers) {
observer.update(latestPost);
}
}
public void postNewBlog(String blog) {
this.latestPost = blog;
notifyObservers();
}
}
具体观察者(Concrete Observer)
java
public class Follower implements Observer {
private String name;
public Follower(String name) {
this.name = name;
}
@Override
public void update(String message) {
System.out.println(name + " received update: " + message);
}
}
客户端使用演示
java
public class ObserverPatternDemo {
public static void main(String[] args) {
Blog techBlog = new Blog();
Observer alice = new Follower("Alice");
Observer bob = new Follower("Bob");
techBlog.registerObserver(alice);
techBlog.registerObserver(bob);
techBlog.postNewBlog("New Java Features Released!");
}
}
对应的类图:
