[Design Pattern] Observer Pattern
16 Feb 2018Observer Pattern
객체의 상태 변화를 다른 객체들에게 통지하고 싶을 때 사용하는 패턴
예시 상황
웹사이트가 응답 속도가 느리거나 연결이 안 되면 알림을 보내는 서비스를 구현한다.
public class StatusChecker {
private EmailSender emailSender;
private SmsSender smsSender;
private Messenger messenger;
public void check() {
Status status = loadStatus();
// 웹사이트의 상태가 비정상일 경우 이메일과 SMS 알림을 보낸다.
if (status.isNotNormal) {
emailSender.sendEmail(status);
smsSender.sendSms(status);
messenger.sendMessage(status);
}
}
}
옵저버 패턴 적용
옵저버 패턴에서 주제(subject)에 해당하는 클래스의 구현
주제(subject)는 두가지 책임을 갖는다.
- 옵저버 목록 관리: 옵저버를 등록하고 제거할 수 있는 메서드를 제공한다.
- 상태의 변경이 발생하면 등록된 옵저버에게 변경 내역을 알린다.
public abstract class StatusSubject {
private List<StatusObserver> observers = new ArrayList<StatusObserver>();
// 옵저버를 추가한다.
public void add(StatusObserver observer) {
observers.add(observer);
}
// 옵저버를 제거한다.
public void remove(StatusObserver observer) {
observers.remove(observer);
}
// 옵저버에게 변경 내역을 알린다.
public void notifyStatus(Status status) {
for (StatusObserver observer: observers) {
observer.onAbnormalStatus(status);
}
}
}
옵저버에게 알림이 필요한 콘크리트 클래스의 구현
public class StatusChecker extends StatusSubject {
public void check() {
Status status = loadStatus();
if (status.isNotNomal()) {
super.notifyStatus(status);
}
}
}
옵저버 객체를 구현한 클래스는 주제 객체가 호출하는 메서드에서 필요한 기능을 구현하면 된다.
옵저버 인터페이스
public interface StatusObserver {
void onAbnormalStatus(Status status);
}
콘크리트 옵저버 클래스
public class StatusEmailSender implements StatusObserver {
@Override
public void onAbnormalStatus(Status status) {
sendEmail(status);
}
}
StatusChecker의 사용
public class Client {
public void checkStatus() {
StatusChecker statusChecker = new StatusChecker();
statusChecker.add(new StatusEmailSender()); // 옵저버로 등록
// statusChecker는 상태를 체크해서 등록된 옵저버에 알림을 보낸다.
statusChecker.check();
}
}