객체 지향 프로그래밍에서 사용되는 디자인 패턴 중 하나로, 객체의 상태 변화가 있을 때 이를 감지하여 자동으로 다른 객체들에게 알리고 업데이트하는 패턴
1. 주요 구성 요소
- 주체 (Subject): 상태를 관리하며, 상태가 변화할 때 옵저버들에게 알림을 보냄.
- 옵저버 (Observer): 주체의 상태 변화를 감지하고 그에 따라 반응함.
- 구독 (Subscription): 옵저버가 주체에 등록되어 상태 변화를 구독.
2. 흐름
- 주체(Subject)가 상태를 변경함.
- 주체(Subject)는 자신에게 등록된 옵저버들(Observer)에게 변경 사항을 통지함.
- 옵저버(Observer)는 주체(Subject)의 상태 변화를 감지하고, 그에 맞는 행동을 취함.
3. 예시
- 뉴스 사이트 예시
- 뉴스 사이트의 주체인 뉴스 서버가 새로운 기사가 추가되면, 이를 구독하고 있는 옵저버들(예: 이메일 구독자, 모바일 앱 사용자)에게 자동으로 알림을 보냄.
- 클라이언트가 일정 시간 간격으로 상태 확인을 위한 요청을 보냄.
- 클라이언트가 새 기사를 구독하고 있으면, 기사가 업데이트 될 때마다 이메일이나 푸시 알림을 통해 변경 사항을 받음.
- 주식 거래 예시
- 주식의 주체인 주식 시장에서 주식 가격이 변동하면, 주식을 구독하는 옵저버들(예: 투자자, 거래 시스템)은 가격 변화에 대한 알림을 받음.
- 주식의 가격이 일정 비율 이상 변동하면 자동으로 알림을 보냄.
4. 장점
- Loose Coupling: 주체와 옵저버는 서로 독립적이기 때문에 주체의 변경이 옵저버에 영향을 주지 않음.
- 동적 구독: 옵저버는 필요에 따라 주체에 등록하거나 해제할 수 있음.
5. 단점
- 과도한 알림: 옵저버가 많으면 불필요한 알림이 많아질 수 있음.
- 상태 변화가 빈번한 경우: 많은 옵저버들에게 빈번하게 상태 변화 알림을 보내는 것이 성능에 영향을 줄 수 있음.
6. 활용 예시
- 주식 거래 시스템
- 날씨 정보 제공 시스템
- 소셜 미디어 알림 시스템
7. 예제 코드
public interface PubListener {
void add(SubListener sub);
void remove(SubListener sub);
void notifyChange(String msg);
}
import ch07.sub.SubListener;
import java.util.ArrayList;
import java.util.List;
public class Pub implements PubListener{
// 1. 구독자 명단
List<SubListener> subList = new ArrayList<>();
@Override
public void add(SubListener sub) {
subList.add(sub);
}
@Override
public void remove(SubListener sub) {
subList.remove(sub);
}
// 2. 책임: 물건이 들어오면, 구독자들에게 알림을 보냄
@Override
public void notifyChange(String msg) {
// 5초 잠자기
for (int i = 0; i < 6; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
System.out.print(".");
}
// 구독자들에게 알림주기
for (SubListener sub : subList) {
sub.update(msg);
}
}
}
public interface SubListener {
void update(String msg);
}
public class Sub1 implements SubListener{
@Override
public void update(String msg) {
System.out.println("sub1이 받은 알림: " + msg);
}
}
public class Sub2 implements SubListener{
@Override
public void update(String msg) {
System.out.println("sub2가 받은 알림: " + msg);
}
}
import ch07.pub.Pub;
import ch07.pub.PubListener;
import ch07.sub.Sub1;
import ch07.sub.Sub2;
import ch07.sub.SubListener;
// 옵저버 패턴 >> 콜백
public class App {
public static void main(String[] args) {
// 객체 생성 init
PubListener pub = new Pub();
SubListener sub1 = new Sub1();
SubListener sub2 = new Sub2();
// 2. 구독
pub.add(sub1);
pub.add(sub2);
// 3. 상품 들어옴 (가정)
// 4. notifyChange 호출
pub.notifyChange("상품 입고됨");
}
}
7.1. 출력문
......sub1이 받은 알림: 상품 입고됨
sub2가 받은 알림: 상품 입고됨
현재 코드에서는 상태의 변화를 표현하고자 Thread.sleep();을 이용하여 지연 시간을 주어 구현한 상태.
아무 메시지가 없을때는 “.”으로 표현되다가 메시지를 입력 받으면 해당 메시지가 각 sub에 출력되는 모습
Share article