1. 개요
- 옵저버 디자인 패턴(Observer Design Pattern)은 관찰자
observer
가 관찰대상subject
이 상태변화가 있을 때마다 관찰자에게 알리고, 알림을 받은 관찰자가 행동하도록 하는 패턴이다.
2. 상황
- 한 개의 관찰 대상자
subject
가 여러개의 관찰자observer
를 가질 때
3. 다이어그램
3.1. 설명
Subject
Observer
에 대한 등록, 해제, 알림 전송 등을 관리하는 역할을 수행한다.- 일반적으로 하나 이상의
Observer
를 관리한다. - 상태가 변경될 때마다 등록된 모든
Observer
에게 상태 변화를 알린다.
Observer
Subject
의 상태 변화에 대한 알림을 수신하고 처리하는 역할을 수행한다.Subject
에서 발생한 알림을 받은 후 필요한 작업을 수행하거나 상태를 업데이트한다.
4. 구현
public interface Observer {
public void update();
}
class ObserverA implements Observer {
@Override
public void update() {
System.out.println("ObserverA: Received an update.");
}
}
class ObserverB implements Observer {
@Override
public void update() {
System.out.println("ObserverB: Received an update.");
}
}
public interface Subject {
public void addObs(Observer o);
public void removeObs(Observer o);
public void notifyObs();
}
public class ConcreteSubject implements Subject {
private List<Observer> observers = new ArrayList<>();
@Override
public void addObs(Observer o) { observers.add(o); }
@Override
public void removeObs(Observer o) { observers.remove(o); }
@Override
public void notifyObs() {
System.out.println("ConcreteSubject: Notifying observers...");
for (Observer o : observers) o.update();
}
}
public class Client {
public static void main(String[] args) {
Subject s = new ConcreteSubject();
Observer oA = new ObserverA();
Observer oB = new ObserverB();
s.addObs(oA);
s.addObs(oB);
s.notifyObs();
s.removeObs(oA);
s.notifyObs();
}
}
5. 예시
public interface Observer {
void update(Product p);
}
class UserObserver implements Observer {
private String username;
public UserObserver(String username) {
this.username = username;
}
@Override
public void update(Product p) {
System.out.println(username + "님, " + p.getName() + "이 할인 중 입니다.");
System.out.println(p.getPrice() + "원 (" + 100 * p.getDiscountRate() + "% 할인)");
}
}
public abstract class Subject {
private List<Observer> observers = new ArrayList<>();
public void addO(Observer o) { observers.add(o); }
public void removeO(Observer o) { observers.remove(o); }
public void notifyO(Product p) { for (Observer o : observers) o.update(p); }
}
public class Product extends Subject {
private String name;
private int price;
private double discountRate;
public String getName() { return name; }
public int getPrice() { return price; }
public double getDiscountRate() { return discountRate; }
public Product(String name, int price) {
this.name = name;
this.price = price;
discountRate = .0;
}
public void discount(double rate) {
discountRate = rate;
price *= (1 - rate);
notifyO(this);
}
}
public class Client {
public static void main(String[] args) {
Product p = new Product("Macbook", 1_000_000);
Observer james = new UserObserver("James");
Observer jane = new UserObserver("Jane");
p.addO(james);
p.addO(jane);
p.discount(.2);
p.removeO(james);
p.discount(.3);
}
}
실행결과
James님, Macbook이 할인 중 입니다.
800000원 (20.0% 할인)
Jane님, Macbook이 할인 중 입니다.
800000원 (20.0% 할인)
Jane님, Macbook이 할인 중 입니다.
560000원 (30.0% 할인)
6. 장단점
6.1. 장점
- 관찰 대상
subject
의 상태 변경을 자동으로 감지할 수 있다. - OCP를 준수한다.
6.2. 단점
- 코드 복잡도가 증가한다.
observer
객체를 해지하지 않으면 메모리 누수가 발생할 수 있다.
관련 포스팅
728x90
'Develop > Design Pattern' 카테고리의 다른 글
[Design Pattern] 단순 팩토리 (Simple Factory) 패턴 (0) | 2023.12.18 |
---|---|
[Design Pattern] 프로토타입 (Prototype) 패턴 (0) | 2023.11.15 |
[Design Pattern] 메멘토 (Memento) 패턴 (0) | 2023.11.13 |
[Design Pattern] 명령 (Command) 패턴 (0) | 2023.11.06 |
[Design Pattern] 경량 (Flyweight) 패턴 (0) | 2023.10.22 |