A A
[Design Pattern] Observer Pattern - ์˜ต์ €๋ฒ„ ํŒจํ„ด

Observer Pattern

Observer๋Š” ๊ด€์ฐฐํ•˜๋Š” ์‚ฌ๋žŒ์˜ ์˜๋ฏธ์ž…๋‹ˆ๋‹ค.
  • Observer ํŒจํ„ด์—์„œ๋Š” ๊ด€์ฐฐ ๋Œ€์ƒ(Subject)์˜ ์ƒํƒœ๊ฐ€ ๋ณ€ํ™”ํ•˜๋ฉด ๊ด€์ฐฐ์ž(Observer)์—๊ฒŒ ์•Œ๋ ค์ค๋‹ˆ๋‹ค.
  • Obsever ํŒจํ„ด์€ ์ƒํƒœ ๋ณ€ํ™”์— ๋”ฐ๋ฅธ ์ฒ˜๋ฆฌ๋ฅผ ๊ธฐ์ˆ ํ•  ๋•Œ ํšจ๊ณผ์ ์ž…๋‹ˆ๋‹ค.

์–ด๋– ํ•œ ์ด๋ฒคํŠธ๊ฐ€ ์ผ์–ด๋‚ฌ์„ ๋•Œ ์ด๋ฒคํŠธ๋ฅผ ๋ฐ”๋ผ๋ณด๋˜ ๊ฐ์‹œ์ž๋“ค์ด ๋ฐ”๋กœ ๋ฐ˜์‘ํ•  ์ˆ˜ ์žˆ๋Š” Pattern ์ž…๋‹ˆ๋‹ค.
-> Subscriber, Listener Pattern 


Observer Pattern์ด ์•„๋‹Œ ๊ฒฝ์šฐ

  • ์ด๋ฒคํŠธ๊ฐ€ ์ผ์–ด๋‚ฌ๋Š”์ง€ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด 1์ดˆ, 1๋ถ„, 1์‹œ๊ฐ„๋งˆ๋‹ค ํ™•์ธ์„ ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.
  • ์ด๋Ÿฌํ•œ ๋ฐฉ๋ฒ•์„ polling ์ด๋ผ๊ณ  ํ•˜์—ฌ ํ•„์š” ์—†๋Š” ๋ฆฌ์†Œ์Šค ๋‚ญ๋น„๊ฐ€ ์ƒ๊น๋‹ˆ๋‹ค.
  • Polling ์ฃผ๊ธฐ๊ฐ€ 1์‹œ๊ฐ„์ผ ๊ฒฝ์šฐ, 1์‹œ๊ฐ„ ์ด๋‚ด์— ์ด๋ฒคํŠธ ์ผ์–ด๋‚˜๋‹ค๊ฐ€ ์‚ฌ๋ผ์ง„๋‹ค๋ฉด ์ด๋ฒคํŠธ๊ฐ€ ์ผ์–ด๋‚ฌ๋Š”์ง€ ์•Œ ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ด ์—†์Šต๋‹ˆ๋‹ค.

Observer Pattern์„ ์‚ฌ์šฉํ•œ ๊ฒฝ์šฐ

๋ฒคํŠธ๋ฅผ ๋ฐ”๋ผ๋ณด๊ณ  ์žˆ๋˜ Obsever๋“ค์ด ๋ฐ”๋กœ ๋ฐ˜์‘์„ ํ•ฉ๋‹ˆ๋‹ค.
  • Observer Pattern ์˜ˆ์‹œ
    • ์•„์นจ์— ์•Œ๋žŒ์ด ์šธ๋ฆฌ๋ฉด ๊ฐ€์กฑ ๊ตฌ์„ฑ์›๋“ค์ด ๋ชจ๋‘ ์ผ์–ด๋‚˜์„œ ์นจ๊ตฌ ์ •๋ฆฌ๋ฅผ ํ•˜๊ณ  ์•„์นจ ์‹์‚ฌ๋ฅผ ํ•œ๋‹ค.
    • ํƒ๋ฐฐ๊ฐ€ ๋„์ฐฉํ•˜๋ฉด ํ˜„๊ด€๋ฌธ ์•ž์œผ๋กœ ๋‹ฌ๋ ค ๊ฐ‘๋‹ˆ๋‹ค.
    • ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด ๊ด€๋ จ ํ•จ์ˆ˜๊ฐ€ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค.
๋ชจ๋‘ ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ, Obsever๋“ค์ด ๋ฐ”๋กœ ๋ฐ˜์‘ํ•˜๋Š” ํŒจํ„ด์ž…๋‹ˆ๋‹ค.

Observer Pattern ํด๋ž˜์Šค ๊ตฌ์กฐ

  • Observer class
    • ์ด๋ฒคํŠธ ๊ฐ์‹œํ•˜๋Š” Observer ์ž…๋‹ˆ๋‹ค.
    • Update(): ์–ด๋–ค ์ด๋ฒคํŠธ๊ฐ€ ์ผ์–ด๋‚ฌ์„ ๋•Œ ๋™์ž‘ํ•  ํ•จ์ˆ˜ ์ž…๋‹ˆ๋‹ค.
    • Base class ์ƒ์†๋ฐ›๋Š” ์‹ค์ œ Observer์ธ Observer1, Observer2
  • Event class
    • Event ์•ˆ์—๋Š” ์ด๋ฅผ ๋ฐ”๋ผ๋ณด๋Š” Observer๋ฅผ ์†Œ์œ ํ•ฉ๋‹ˆ๋‹ค.
    • Observer Object์˜ reference๋“ค์„ ๋ฆฌ์ŠคํŠธ๋กœ ๋ณด๊ด€ํ•ฉ๋‹ˆ๋‹ค.
    • register(): ์—ฌ๋Ÿฌ Observer๋“ค์„ ๋ฆฌ์ŠคํŠธ๋กœ ์ถ”๊ฐ€ํ•˜๋Š” ํ•จ์ˆ˜ํ•ฉ๋‹ˆ๋‹ค.
    • notfiy(): ์–ด๋–ค event๊ฐ€ ์ผ์–ด๋‚ฌ์„ ๋•Œ ์†Œ์œ ํ•˜๊ณ  ์žˆ๋Š” Observer๋“ค์˜ Update() ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.

 

Observer Pattern Example

๊ฐ•์•„์ง€, ๊ณ ์–‘์ด๊ฐ€ Observer / ๋™๋ฌผ์˜ ์ฃผ์ธ์ด Event๊ฐ€ ๋˜๋Š” ๊ตฌ์กฐ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
(์ฃผ์ธ์ด ์ง‘์ด ๋“ค์–ด์˜ค๊ฑฐ๋‚˜ ์ง‘ํ•ฉ๋ช…๋ น ๋‚ด๋ฆฌ๋ฉด ๋™๋ฌผ๋“ค์ด ๋ฐ˜์‘ํ•ฉ๋‹ˆ๋‹ค.)
class Observer:
    def update(self):
        pass

class Cat(Observer):
    def update(self):
        print('meow')

class Dog(Observer):
    def update(self):
        print('bark')

Observer ํด๋ž˜์Šค

  • ์ด๋ฒคํŠธ๋ฅผ ๊ฐ์‹œํ•˜๋Š” Base ํด๋ž˜์Šค์ž…๋‹ˆ๋‹ค.
  • update() ๋ฉ”์†Œ๋“œ๋Š” ์ด๋ฒคํŠธ์— ๋ฐ˜์‘ํ•˜๋Š” ํ•จ์ˆ˜์ž…๋‹ˆ๋‹ค.
  • Cat๊ณผ Dog ํด๋ž˜์Šค๋Š” Observer ํด๋ž˜์Šค๋ฅผ ์ƒ์†๋ฐ›์Šต๋‹ˆ๋‹ค.
    • Cat ํด๋ž˜์Šค๋Š” update()์—์„œ "meow"๋ผ๊ณ  ๋ฐ˜์‘ํ•ฉ๋‹ˆ๋‹ค.
    • Dog ํด๋ž˜์Šค๋Š” update()์—์„œ "bark"๋ผ๊ณ  ๋ฐ˜์‘ํ•ฉ๋‹ˆ๋‹ค.

 

class Owner:
    def __init__(self):
        self.animals = []

    def register(self, animal):
        self.animals.append(animal)

    def notify(self):
        for animal in self.animals:
            animal.update()
owner = Owner()
cat = Cat()
dog = Dog()

owner.register(cat)
owner.register(dog)
owner.notify()

# meow
# bark
  • Owner, Cat, Dog ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
  • Owner์— cat๊ณผ dog์„ register()๋ฅผ ์ด์šฉํ•˜์—ฌ ๋“ฑ๋กํ•ฉ๋‹ˆ๋‹ค.
  • Owner๊ฐ€ notify()๋ฅผ ํ†ตํ•ด ์‹ ํ˜ธ๋ฅผ ๋ณด๋‚ด๋ฉด Owner๊ฐ€ ์†Œ์œ ํ•œ cat๊ณผ dog์ด ๋ฐ˜์‘ํ•ฉ๋‹ˆ๋‹ค.