1. 소개
1.1 정의
관찰자 모드 : 관찰자 모드는 발행 / 구독 (발행 / 구독) 모드라고도합니다. 개체 간의 일대 다 종속성 관계를 정의 합니다. 각 개체의 상태가 변경되면 해당 개체에 종속 된 모든 개체에 알림이 전송되고 자동으로 업데이트됩니다.
1.2 역할
관찰자 모드를 사용하면 좋은 디커플링이 될 수 있습니다. 커플 링의 양 당사자가 보자 추상화에 의존 , 오히려 콘크리트보다 . 변경 사항이 다른 쪽의 변경 사항에 영향을 미치지 않도록합니다.
2. 모드 원리
2.1 UML 구조 클래스 다이어그램
2.2 모드 구성
구성 (역할) | 관계 | 효과 |
Abstract Subject (Subject)는 Abstract Observed라고도합니다. | 특정 관찰자의 부모 클래스 | 특정 관찰자의 공개 인터페이스 설명 |
ConcreteSubject (구체적인 관찰) | 추상적 인 주제의 하위 카테고리; | 특정 관찰자 설명 |
추상 관찰자 (관찰자) | 구체적인 관찰자의 부모 클래스 | 특정 관찰자의 공개 인터페이스 설명 |
콘크리트 관찰자 (ConcreteObserver) | 추상 관찰자의 하위 클래스 | 특정 관찰자 설명 |
2.3 각 역할의 역할
주제 : 추상 주제 (추상 관찰자) . 추상 테마는 컬렉션의 모든 관찰자 개체를 저장하며 각 테마에는 여러 관찰자가있을 수 있습니다. 추상 테마는 관찰자 객체를 추가하고 삭제할 수있는 인터페이스를 정의합니다.
ConcreteSubject : 특정 주제 (특정 관찰자) . 이 역할은 관련 상태를 특정 관찰자 개체에 저장하고 특정 주체의 내부 상태가 변경되면 등록 된 모든 관찰자에게 알림을 보냅니다.
관찰자 : 추상 관찰자 , 구체적인 관찰자의 추상 클래스입니다. 테마 변경 알림을받을 때 자체적으로 변경 될 수 있도록 업데이트 인터페이스를 정의합니다.
ConcreteObserver : 테마 변경 알림을받을 때 상태를 업데이트 할 수 있도록 추상 관찰자가 정의한 업데이트 인터페이스를 구현 하는 구체적인 관찰자 입니다.
2.4 사용 단계
1 단계 : 추상 관찰자 클래스 (인터페이스) 생성 및 업데이트 된 메서드 정의
2 단계 : 특정 옵저버 생성 및 업데이트 메서드 구현
3 단계 : 추상 관찰자 (추상 주제) 생성 , 추가, 삭제, 알림 (추상 관찰자) 등의 방법 제공
4 단계 : 구체적인 옵저버 생성 (추상 옵저버 상속 / 구현) 및 추상 옵저버 방법 구현
5 단계 : 클라이언트 호출
3. 관찰자 패턴의 간단한 구현
사례 설명 : WeChat 공식 계정 을 예로 들어 보겠습니다. WeChat 사용자가 관찰자이고 WeChat 공식 계정이 관찰되었다고 가정합니다. 공식 계정 "프로그램"을 팔로우하는 WeChat 사용자가 여러 명 있으며, 이러한 가입 된 WeChat 사용자는 공식 계정이 업데이트되면 알림을 받게됩니다.
1 단계 : 추상 관찰자 클래스 (인터페이스) 생성 및 업데이트 된 메서드 정의
/***
* 抽象观察者
* 定义了一个update()方法,当被观察者调用notifyObservers()方法时,观察者的update()方法会被回调。
* @author zhourui
*
*/
public interface Observer {
void update(String message);
}
2 단계 : 특정 옵저버 생성 및 업데이트 메서드 구현
/**
* 具体观察者,实现了update方法
*/
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() {
System.out.println(name + "收到推送消息:" + message);
}
}
3 단계 : 추상 관찰자 (추상 주제) 생성 , 추가, 삭제, 알림 (추상 관찰자) 등의 방법 제공
/***
* 抽象被观察者接口
* 声明了添加、删除、通知观察者方法
* @author zhourui
*
*/
public interface Observerable {
void registerObserver(Observer observer);
void removeObserver(Observer observer);
void notifyObserver();
}
4 단계 : 구체적인 옵저버 생성 (추상 옵저버 상속 / 구현) 및 추상 옵저버 방법 구현
/**
* 具体被观察者,也就是微信公众号服务
* 实现了Observerable接口,对Observerable接口的三个方法进行了具体实现
*
* @author zhourui
*/
public class WeChatServer implements Observerable {
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 (Observer obs : list) {
obs.update(message);
}
}
public void setInfomation(String s) {
this.message = s;
System.out.println("微信服务更新消息: " + s);
//消息更新,通知所有观察者
notifyObserver();
}
}
5 단계 : 클라이언트 호출
/**
* 观察者模式测试类
*/
public class ObserverTest {
public static void main(String[] args) {
//创建具体被观察者对象
WeChatServer weChatServer = new WeChatServer();
//创建具体观察者对象
Observer userZhang = new User("张三");
Observer userLi = new User("李四");
Observer userWang = new User("王五");
//具体被观察者注册具体观察者
weChatServer.registerObserver(userZhang);
weChatServer.registerObserver(userLi);
weChatServer.registerObserver(userWang);
weChatServer.setInfomation("PHP是世界上最好的语言");
System.out.println("------------------------------------------------------");
weChatServer.removeObserver(userZhang);
weChatServer.setInfomation("PHP再好但是我学的是Java语言");
}
}
4. 옵저버 패턴의 장단점
4.1 장점
• 관찰자와 관찰자간에 추상적 인 결합이있어 확장하기 쉽습니다.
• 방아쇠 메커니즘의 확립을 촉진
4.2 단점
• 개발 효율성 및 운영 효율성이 상대적으로 낮을 수 있습니다.
• 옵저버가 멈춰 있으면 전체 실행 효율성에 영향을 미칩니다 (비동기 방식 사용 가능).
5. 관찰자 모드 사용 시나리오
• 행동 시나리오를 연결합니다. 참고 : 연결 동작은 조합 관계가 아니라 분리 가능합니다.
• 시간 다단계 출발 장면.
• 메시지 대기열 및 이벤트 버스의 처리 메커니즘과 같은 시스템 간 메시지 교환 시나리오.