As i wish

[Design pattern] Observer pattern(옵저버 패턴) 본문

Design Pattern

[Design pattern] Observer pattern(옵저버 패턴)

어면태 2019. 1. 21. 00:18

안녕하세요.

오늘은 디자인패턴 중에 옵저버 패턴에 대하여 알아보겠습니다.


일단 옵저버 패턴이란..

- 한 객체의 상태가 바뀌면 그 객체에 의존하는 다른 객체들한테 연락이 가고 자동으로 내용이 갱신되는 방식으로 일대다(one-to-many)의존성을 정의합니다.


즉 어떤 주제에 관해 듣고 싶은 옵저버가 있다면 그 주제를 등록하고 그 주제가 변경 될때 등록하고 있던 옵저버들에게 정보를 전달해주고

정보를 받은 옵저버들은 그에 따른 행동을 하게 되는 거죠.

또한 옵저버는 주제를 등록 할 수도 있고 주제에 탈퇴를 할 수도 있죠.


그럼 일단 다이어그램부터 확인해 보시죠,






위에 처럼 주제 객체를 만들어주고 옵저버 객체를 만들어 줍니다.

다이어 그램에서는 빠져 있지만 Observer 객체를 상속받은 아이들에게는 remove라는 함수도 넣어줘서 주제에 탈퇴 할 수도 있도록 만들어 주었습니다.


즉 WeatherData란 주제가 있고 여기 주제를 옵저버들(CurrentCondition, StaticsDisplay)들이 등록 할 수도 있고 탈퇴 할 수도 있는데

만약 등록이 되어있다면 주제가 변경시 이 옵저버들이 다 주제 변경에 대한 것을 인지하고 각자 할일을 하게 된다는 거죠.


그럼 코드로 만나보겠습니다. 역시나 파이썬으로 구성했습니다.


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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# -*- coding: utf-8 -*-
# Strategy Pattern
 
import abc
 
class Subject:
  __metaclass__ = abc.ABCMeta
 
  @abc.abstractmethod
  def register_observer(self):
    pass
 
  @abc.abstractmethod
  def remove_observer(self):
    pass
 
  @abc.abstractmethod
  def notify_observer(self):
    pass
 
class Observer:
  __metaclass__ = abc.ABCMeta
 
  @abc.abstractmethod
  def update(self):
    pass
 
class WeatherData(Subject):
  def __init__(self):
    self.observers = []
    self.temperature = 0
    self.humidity = 0
    self.pressure = 0
 
  def register_observer(self, observer):
    self.observers.append(observer)
 
  def remove_observer(self, observer):
    self.observers.remove(observer)
 
  def notify_observer(self):
    for observer in self.observers:
      observer.update(self.temperature, self.humidity, self.pressure)
 
  def get_temperature(self):
    return self.temperature
 
  def get_humidity(self):
    return self.humidity
 
  def get_pressure(self):
    return self.pressure
 
  def measurements_changed(self):
    self.notify_observer()
 
  def set_measurements(self, temperature, humidity, pressure):
    self.temperature = temperature
    self.humidity = humidity
    self.pressure = pressure
    self.measurements_changed()
 
class CurrentCondition(Observer):
  def __init__(self, subject):
    self.subject = subject
    self.subject.register_observer(self)
 
  def update(self, temperature, humidity, pressure):
    self.temperature = temperature
    self.humidity = humidity
    self.pressure = pressure
    self.display()
 
  def remove(self):
    self.subject.remove_observer(self)
 
  def display(self):
    print ('Current condition temp: %s hum: %s press: %s'
           %(self.temperature, self.humidity, self.pressure))
 
class StaticsDisplay(Observer):
  def __init__(self, subject):
    self.subject = subject
    self.subject.register_observer(self)
 
  def update(self, temperature, humidity, pressure):
    self.temperature = temperature
    self.humidity = humidity
    self.pressure = pressure
    self.display()
 
  def remove(self):
    self.subject.remove_observer(self)
 
  def display(self):
    print ('Static display temp: %s hum: %s press: %s'
           %(self.temperature, self.humidity, self.pressure))
 
print("###START####")
 
weather_data = WeatherData()
current_condition = CurrentCondition(weather_data)
statics_display = StaticsDisplay(weather_data)
 
weather_data.set_measurements(105030)
weather_data.set_measurements(206040)
 
print("###Remove static_display observer###")
statics_display.remove()
 
weather_data.set_measurements(123)
 
 
cs



Comments