Observer

Observer ํŒจํ„ด์€ ํ•œ ๊ฐ์ฒด(Subject)์˜ ์ƒํƒœ ๋ณ€ํ™”์— ๋”ฐ๋ผ ์—ฌ๋Ÿฌ ๊ฐ์ฒด(Observer)๋“ค์ด ์ž๋™์œผ๋กœ ๊ฐฑ์‹ ๋˜๋„๋ก ํ•˜๋Š” 1:N ๊ด€๊ณ„๋ฅผ ๊ตฌ์„ฑํ•˜๋Š” ๋””์ž์ธ ํŒจํ„ด์ž…๋‹ˆ๋‹ค.

           +----------------------+
           |      Subject         |  <-- ์ƒํƒœ ๋ณ€๊ฒฝ์„ ํ†ต๋ณดํ•˜๋Š” ๊ฐ์ฒด
           +----------------------+
           | + attach(o:Observer) |
           | + detach(o:Observer) |
           | + notifyObservers()  |
           +----------------------+
                    โ”‚
          โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
          โ”‚         ...       โ”‚   1:N ๊ด€๊ณ„
          โ”‚                   โ”‚
   +--------------+    +--------------+
   |  Observer    |    |  Observer    |  <-- ์ƒํƒœ ๋ณ€๊ฒฝ์„ ๋ฐ›์•„ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฐ์ฒด๋“ค
   +--------------+    +--------------+
   | + update()   |    | + update()   |
   +--------------+    +--------------+

์ฆ‰, Subject์™€ Observer ๊ฐ„์˜ ๋А์Šจํ•œ ๊ฒฐํ•ฉ(loose coupling)์„ ํ†ตํ•ด, ๋ฐ์ดํ„ฐ ๋ณ€๊ฒฝ์ด ์žˆ์„ ๋•Œ ์ƒ๋Œ€ ํด๋ž˜์Šค์— ์ง์ ‘ ์˜์กดํ•˜์ง€ ์•Š๊ณ  Observer๋“ค์—๊ฒŒ ๋ณ€๊ฒฝ ์‚ฌ์‹ค์„ ์•Œ๋ ค์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

How do code ?

// Observer ์ธํ„ฐํŽ˜์ด์Šค: Subject์˜ ์ƒํƒœ ๋ณ€๊ฒฝ์„ ํ†ต๋ณด๋ฐ›๊ธฐ ์œ„ํ•œ ๋ฉ”์„œ๋“œ ์ •์˜
public interface Observer {
    void update(String message);
}

// Subject ์ธํ„ฐํŽ˜์ด์Šค: Observer๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ๋ฉ”์„œ๋“œ ์ •์˜
public interface Subject {
    void attach(Observer observer);
    void detach(Observer observer);
    void notifyObservers();
}

// ConcreteSubject: ์‹ค์ œ๋กœ Observer๋“ค์„ ๊ด€๋ฆฌํ•˜๊ณ , ์ƒํƒœ ๋ณ€๊ฒฝ ์‹œ ํ†ต๋ณดํ•˜๋Š” ํด๋ž˜์Šค
public class ConcreteSubject implements Subject {
    private final List<Observer> observers = new ArrayList<>();
    private String message;

    @Override
    public void attach(Observer observer) {
        observers.add(observer);
    }

    @Override
    public void detach(Observer observer) {
        observers.remove(observer);
    }

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

    // ์ƒํƒœ ๋ณ€๊ฒฝ ์‹œ Observer๋“ค์—๊ฒŒ ํ†ต๋ณด
    public void setMessage(String message) {
        this.message = message;
        notifyObservers();
    }
}

// ConcreteObserver: ์ƒํƒœ ๋ณ€๊ฒฝ์„ ๋ฐ›์•„ ์ฒ˜๋ฆฌํ•˜๋Š” ํด๋ž˜์Šค
public class ConcreteObserver implements Observer {
    private final String name;

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

    @Override
    public void update(String message) {
        System.out.println(name + "์ด(๊ฐ€) ์—…๋ฐ์ดํŠธ ๋ฐ›์Œ: " + message);
    }
}

Subject (Observable ๊ฐ์ฒด)

  • Observer๋ฅผ ๋“ฑ๋ก(attach)ํ•˜๊ฑฐ๋‚˜ ํ•ด์ œ(detach)ํ•˜๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ๊ฐ€์ง€๊ณ , ์ƒํƒœ ๋ณ€๊ฒฝ ์‹œ ๋ชจ๋“  Observer๋“ค์—๊ฒŒ ์•Œ๋ฆฌ๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.

  • ๋‚ด๋ถ€ ์ƒํƒœ(์˜ˆ: ๋ฉ”์‹œ์ง€)๊ฐ€ ๋ณ€๊ฒฝ๋˜๋ฉด notifyObservers()๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ๋“ฑ๋ก๋œ Observer๋“ค์—๊ฒŒ ๋ณ€๊ฒฝ ๋‚ด์šฉ์„ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.

Observer

  • Subject๋กœ๋ถ€ํ„ฐ ์ƒํƒœ ๋ณ€๊ฒฝ์„ ํ†ต๋ณด๋ฐ›๊ธฐ ์œ„ํ•œ update() ๋ฉ”์„œ๋“œ๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.

  • ๊ฐ๊ฐ์˜ ConcreteObserver๋Š” ์ด ๋ฉ”์„œ๋“œ๋ฅผ ๊ตฌํ˜„ํ•˜์—ฌ ์ž์‹ ๋งŒ์˜ ๋ฐฉ์‹์œผ๋กœ ์ƒํƒœ ๋ณ€๊ฒฝ์— ๋Œ€์‘ํ•ฉ๋‹ˆ๋‹ค.

์žฅ์ 

  • Subject์™€ Observer ๊ฐ„์˜ ๊ฒฐํ•ฉ๋„๋ฅผ ๋‚ฎ์ถฐ, ์„œ๋กœ ๋…๋ฆฝ์ ์œผ๋กœ ํ™•์žฅ ๋ฐ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ํ•œ ๊ฐ์ฒด์˜ ์ƒํƒœ ๋ณ€๊ฒฝ์ด ์—ฌ๋Ÿฌ ๊ฐ์ฒด์— ์ž๋™์œผ๋กœ ๋ฐ˜์˜๋˜๋ฏ€๋กœ, ๋ฐ์ดํ„ฐ ์ผ๊ด€์„ฑ์„ ์œ ์ง€ํ•˜๊ธฐ ์‰ฝ์Šต๋‹ˆ๋‹ค.

Last updated