Home 옵저버 패턴(Observer Pattern)
Post
Cancel

옵저버 패턴(Observer Pattern)


옵저버 패턴이란?

  • 객체의 상태 변화가 다른 객체들에게 자동으로 통지되는 패턴

구성요소

  • Subject(주체): 상태가 변경될 때 알림을 보내는 주체, 옵저버 객체들을 등록, 삭제하고 상태가 변경될 때 옵저버들에게 알림을 보냄
  • Observer(옵저버): 주체의 상태 변화를 관찰하고 이에 반응하는 객체, 이들은 주체에 등록되어 있으며 주체로부터 알림을 받음

장점

  • 느슨한 결합: 주체와 옵저버는 독립적으로 존재하고, 상호 작용 시 서로 대한 정보가 필요하지 않다.
  • 확장성: 새로운 옵저버를 쉽게 추가하거나 제거하여 시스템을 확장할 수 있다.

단점

  • 복잡성: 옵저버 패턴을 자주 구성하면 구조와 동작을 알아보기 힘들어져 코드 복잡도가 증가한다.
  • 성능 저하 가능성: 다수의 옵저버 객체를 등록 이후 관리를 하지 않는다면 메모리 누수가 발생할 수도 있다.

구현 예제

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
package exam;

import java.util.ArrayList;
import java.util.List;

interface Subject {
  void register(Observer obj);

  void unregister(Observer obj);

  void notifyObservers();

  Object getUpdate(Observer obj);
}

interface Observer {
  void update(Subject subject);
}


class Instagram implements Subject {
  private final List<Observer> observers;
  private String message;

  public Instagram() {
    this.observers = new ArrayList<>();
    this.message = "";
  }

  @Override
  public void register(Observer obj) {
    if (!observers.contains(obj)) {
      observers.add(obj);
    }
  }

  @Override
  public void unregister(Observer obj) {
    observers.remove(obj);
  }

  @Override
  public void notifyObservers() {
    for (Observer observer : this.observers) {
      observer.update(this);
    }
  }

  @Override
  public Object getUpdate(Observer obj) {
    return this.message;
  }

  public void postMessage(String msg) {
    System.out.println("새로운 게시글을 등록했습니다 : " + msg);
    this.message = msg;
    notifyObservers();
  }
}


class Follower implements Observer {
  private String name;

  public Follower(String name) {
    this.name = name;
  }

  @Override
  public void update(Subject subject) {
    String msg = (String) subject.getUpdate(this);
    System.out.println(name + ":: 새 게시물 알림 : " + msg);
  }
}


public class Main {
  public static void main(String[] args) {
    Instagram instagram = new Instagram();
    instagram.register(new Follower("user1"));
    instagram.register(new Follower("user2"));
    instagram.register(new Follower("user3"));

    instagram.postMessage("오늘의 일기");
  }
}


마치며

  • 옵저버 패턴을 사용하면 주체와 옵저버간의 느슨한 결합을 유지할 수 있다.
  • 옵저버 패턴은 DIP(의존성 역전 원칙)을 따르며, 주체가 옵저버에 의존하는 것이 아니라 추상화된 옵저버에 의존한다.
  • 높은 추상화 수준을 유지하면서 객체지향적인 설계를 도와준다.
This post is written by PRO.