CS/๋””์ž์ธ ํŒจํ„ด

[๋””์ž์ธ ํŒจํ„ด] ์˜ต์ €๋ฒ„ ํŒจํ„ด(Observer Pattern)

1eehyunji 2023. 8. 2. 18:10

์˜ต์ €๋ฒ„ ํŒจํ„ด์€ ์ฃผ์ฒด๊ฐ€ ์–ด๋–ค ๊ฐ์ฒด์˜ ์ƒํƒœ ๋ณ€ํ™”๋ฅผ ๊ด€์ฐฐํ•˜๋‹ค๊ฐ€ ์ƒํƒœ ๋ณ€ํ™”๊ฐ€ ์žˆ์„ ๋•Œ๋งˆ๋‹ค ๋ฉ”์„œ๋“œ ๋“ฑ์„ ํ†ตํ•ด์„œ ์˜ต์ €๋ฒ„ ๋ชฉ๋ก์— ์žˆ๋Š” ์˜ต์ €๋ฒ„๋“ค์—๊ฒŒ ๋ณ€ํ™”๋ฅผ ์•Œ๋ ค์ฃผ๋Š” ๋””์ž์ธ ํŒจํ„ด์ด๋‹ค. 

 

์—ฌ๊ธฐ์„œ '์ฃผ์ฒด'๋Š” ๊ฐ์ฒด์˜ ์ƒํƒœ ๋ณ€ํ™”๋ฅผ ์ง€์ผœ๋ณด๊ณ  ์žˆ๋Š” ๊ด€์ฐฐ์ž์ด๋ฉฐ, '์˜ต์ €๋ฒ„'๋“ค์ด๋ž€ ์ด ๊ฐ์ฒด์˜ ์ƒํƒœ ๋ณ€ํ™”์— ๋”ฐ๋ผ ์ „๋‹ฌ๋˜๋Š” ๋ฉ”์„œ๋“œ ๋“ฑ์„ ๊ธฐ๋ฐ˜์œผ๋กœ '์ถ”๊ฐ€ ๋ณ€ํ™” ์‚ฌํ•ญ'์ด ์ƒ๊ธฐ๋Š” ๊ฐ์ฒด๋“ค์„ ์˜๋ฏธํ•œ๋‹ค. 

์ฃผ์ฒด์™€ ๊ฐ์ฒด๊ฐ€ ๋ถ„๋ฆฌ๋œ ์˜ต์ €๋ฒ„ ํŒจํ„ด
์ฃผ์ฒด์™€ ๊ฐ์ฒด๊ฐ€ ํ•ฉ์ณ์ง„ ์˜ต์ €๋ฒ„ ํŒจํ„ด

์˜ต์ €๋ฒ„ ํŒจํ„ด์€ ์ฃผ์ฒด์™€ ๊ฐ์ฒด๋ฅผ ๋”ฐ๋กœ ๋‘์ง€ ์•Š๊ณ  ์ƒํƒœ๊ฐ€ ๋ณ€๊ฒฝ๋˜๋Š” ๊ฐ์ฒด๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๊ตฌ์ถ•ํ•˜๊ธฐ๋„ ํ•œ๋‹ค.

์ด๋Ÿฌํ•œ ์˜ต์ €๋ฒ„ ํŒจํ„ด์„ ํ™œ์šฉํ•œ ๋Œ€ํ‘œ์ ์ธ ์„œ๋น„์Šค๋กœ๋Š” 'ํŠธ์œ„ํ„ฐ'๊ฐ€ ์žˆ๋‹ค.

ํŠธ์œ„ํ„ฐ๋Š” ์ฃผ์ฒด(์ด ๊ฒฝ์šฐ์—” ์ƒํƒœ๊ฐ€ ๋ณ€๊ฒฝ๋˜๋Š” ๊ฐ์ฒด)๊ฐ€ ์ƒˆ๋กœ์šด ํŠธ์œ—์„ ์˜ฌ๋ฆฌ๋ฉด ์ฃผ์ฒด์˜ ํŒ”๋กœ์›Œ๋“ค์—๊ฒŒ ์ƒˆ๋กœ์šด ํŠธ์œ—์ด ์˜ฌ๋ผ์™”๋‹ค๋Š” ์•Œ๋žŒ์„ ์ „์†กํ•œ๋‹ค.

 

์˜ต์ €๋ฒ„ ํŒจํ„ด์€ ์ฃผ๋กœ ์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜ ์‹œ์Šคํ…œ์— ์‚ฌ์šฉํ•˜๊ณ , MVC(Model-View-Controller) ํŒจํ„ด์—๋„ ์‚ฌ์šฉ๋œ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, ์ฃผ์ฒด๋ผ๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋Š” ๋ชจ๋ธ์—์„œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ์ƒ๊ฒจ์„œ update() ๋ฉ”์„œ๋“œ๋กœ ์˜ต์ €๋ฒ„์ธ ๋ทฐ์—๊ฒŒ ์•Œ๋ ค์ฃผ๊ณ  ์ด๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์ปจํŠธ๋กค๋Ÿฌ๊ฐ€ ์ž‘๋™ํ•˜๋Š” ๊ฒƒ์ด๋‹ค. 

 

์ž๋ฐ”์˜ ์˜ต์ €๋ฒ„ ํŒจํ„ด

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

interface Subject {
    public void register(Observer obj);
    public void unregister(Observer obj);
    public void notifyObservers();
    public Object getUpdate(Observer obj);
}

interface Observer {
    public void update(); 
}

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

    public Topic() {
        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() {   
        this.observers.forEach(Observer::update); 
    }

    @Override
    public Object getUpdate(Observer obj) {
        return this.message;
    } 
    
    public void postMessage(String msg) {
        System.out.println("Message sended to Topic: " + msg);
        this.message = msg; 
        notifyObservers();
    }
}

class TopicSubscriber implements Observer {
    private String name;
    private Subject topic;

    public TopicSubscriber(String name, Subject topic) {
        this.name = name;
        this.topic = topic;
    }

    @Override
    public void update() {
        String msg = (String) topic.getUpdate(this); 
        System.out.println(name + ":: got message >> " + msg); 
    } 
}

public class HelloWorld { 
    public static void main(String[] args) {
        Topic topic = new Topic(); 
        Observer a = new TopicSubscriber("a", topic);
        Observer b = new TopicSubscriber("b", topic);
        Observer c = new TopicSubscriber("c", topic);
        topic.register(a);
        topic.register(b);
        topic.register(c); 
   
        topic.postMessage("amumu is op champion!!"); 
    }
}
/*
Message sended to Topic: amumu is op champion!!
a:: got message >> amumu is op champion!!
b:: got message >> amumu is op champion!!
c:: got message >> amumu is op champion!!
*/

์œ„ ์ฝ”๋“œ์—์„  topic์„ ๊ธฐ๋ฐ˜์œผ๋กœ ์˜ต์ €๋ฒ„ ํŒจํ„ด์„ ๊ตฌํ˜„ํ–ˆ๋‹ค. ์ฆ‰, topic์€ ์ฃผ์ฒด์ด์ž ๊ฐ์ฒด๊ฐ€ ๋œ๋‹ค. Subject ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ

class topic implements Subject์—์„œ ๊ตฌํ˜„ํ–ˆ๊ณ , 

Observer a = new TopicSubscriber("a", topic);

์˜ต์ €๋ฒ„๋ฅผ ์„ ์–ธํ•  ๋•Œ ์˜ต์ €๋ฒ„์˜ ์ด๋ฆ„๊ณผ ์–ด๋–ค ํ† ํ”ฝ์˜ ์˜ต์ €๋ฒ„๊ฐ€ ๋  ๊ฒƒ์ธ์ง€ ์„ค์ •ํ–ˆ๋‹ค.

 

์ด ์ฝ”๋“œ์˜ main ํ•จ์ˆ˜์˜ ํ๋ฆ„์„ ๋”ฐ๋ผ๊ฐ€๋ณด๋ฉด

  • topic์ด๋ผ๋Š” ์ฃผ์ฒด์ด์ž ๊ฐ์ฒด๊ฐ€ ๋˜๋Š” Topic ํด๋ž˜์Šค์˜ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.
  • ์•ž์„œ ์ƒ์„ฑํ•œ topic์˜ ์˜ต์ €๋ฒ„๊ฐ€ ๋˜๋Š” a, b, c ์˜ต์ €๋ฒ„ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•œ๋‹ค. 
  • topic.register() ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด์„œ topic๊ฐ์ฒด์— ํ•ด๋‹น ์˜ต์ €๋ฒ„๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ์ง€ ์•Š๋‹ค๋ฉด, topic ๊ฐ์ฒด์˜ observer ArrayList์— ์ถ”๊ฐ€ํ•ด์„œ ํ•ด๋‹น topic ๊ฐ์ฒด์˜ ์˜ต์ €๋ฒ„๋กœ ๋“ฑ๋กํ•œ๋‹ค. 
  • ์˜ต์ €๋ฒ„ a,b,c์˜ ์ฃผ์ฒด์ด์ž ๊ฐ์ฒด์ธ topic์ด postMessage('')๋ฅผ ํ†ตํ•ด์„œ ์–ด๋–ค ๋ฉ”์‹œ์ง€๋ฅผ ์ถœ๋ ฅํ•˜๋Š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ์ƒ๊ธฐ๋ฉด, postMessage ํ•จ์ˆ˜์—์„  ํ•ด๋‹น ๋ฉ”์‹œ์ง€๋ฅผ ์ถœ๋ ฅํ•˜๊ณ  topic์˜ message ์†์„ฑ์— ์ €์žฅํ•œ ๋‹ค์Œ, notifyObserver() ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด์„œ ๋“ฑ๋ก๋œ ์˜ต์ €๋ฒ„๋“ค์˜ update() ๋ฉ”์„œ๋“œ๋ฅผ ์‹คํ–‰ํ•˜๊ฒŒ ํ•œ๋‹ค. 

 

์ถ”๊ฐ€์ ์œผ๋กœ, ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„  ํ”„๋ก์‹œ ๊ฐ์ฒด๋ฅผ ์ด์šฉํ•ด์„œ ์˜ต์ €๋ฒ„ ํŒจํ„ด์„ ๊ตฌํ˜„ํ•  ์ˆ˜๋„ ์žˆ๋Š”๋ฐ ํ”„๋ก์‹œ ๊ฐ์ฒด์— ๋Œ€ํ•ด์„  ๋‹ค๋ฅธ ํฌ์ŠคํŠธ๋กœ ์ž์„ธํ•˜๊ฒŒ ๋‹ค๋ฃฐ ์˜ˆ์ •์ด๋‹ค!