파이썬에서 디자인 패턴 "Observer"를 배우십시오.
■ Observer 패턴(옵저버·패턴)
Observer 패턴이란, 프로그램내의 오브젝트의 이벤트( 이벤트)를 다른 오브젝트에 통지하는 처리로 사용되는 디자인 패턴의 일종.
통지하는 오브젝트측이, 통지되는 오브젝트측에 관찰(영: observe)되는 형태가 되는 것으로부터, 이렇게 불린다.
출판-구독형 모델이라고도 불린다. 암묵적 호출의 원칙과 관계가 깊다.
분산 이벤트 처리 시스템의 구현에도 사용된다. 언어에 따라서는, 이 패턴으로 취급되는 문제는 언어가 가지는 이벤트 처리 구문으로 처리된다.
UML class and sequence diagram
UML 클래스 diagram
(이상 위키피디아(Wikipedia)에서 인용)
□ 비망록
Observer
패턴에서는, 관찰 대상의 상태가 변화하면, 관찰자에게 통지되기 때문에, 상태 변화에 따른 처리를 기술할 때에 유효하다고 합니다.observer
라는 말의 본래의 의미는 「관찰자」입니다만, 실제로는 Observer
역은 능동적으로 「관찰」하는 것이 아니라, Subject
역으로부터 「통지」되는 것을 수동 적으로 기다리고 있는 것이 되므로, Publish-Subscribe
패턴이라고 불리는 일도 있다고 합니다.
확실히 publish(発行)
와 subscribe(購読)
라는 표현이 적절하다고 생각했습니다.
■ "Observer" 샘플 프로그램
실제로 Observer 패턴을 활용한 샘플 프로그램을 움직여서 다음과 같은 동작의 모습을 확인하고 싶습니다.
실제로 Observer 패턴을 활용한 샘플 프로그램을 움직여서 다음과 같은 동작의 모습을 확인하고 싶습니다.
DigitalObserver
는 숫자로 숫자를 표시합니다.GraphicObserver
는 간단한 그래프로 값을 표시합니다.$ python Main.py
DigitObservser: 30
GraphicObserver:******************************
DigitObservser: 48
GraphicObserver:************************************************
DigitObservser: 6
GraphicObserver:******
DigitObservser: 19
GraphicObserver:*******************
DigitObservser: 19
GraphicObserver:*******************
DigitObservser: 45
GraphicObserver:*********************************************
DigitObservser: 8
GraphicObserver:********
DigitObservser: 21
GraphicObserver:*********************
DigitObservser: 40
GraphicObserver:****************************************
DigitObservser: 6
GraphicObserver:******
DigitObservser: 1
GraphicObserver:*
DigitObservser: 9
GraphicObserver:*********
DigitObservser: 26
GraphicObserver:**************************
DigitObservser: 22
GraphicObserver:**********************
DigitObservser: 16
GraphicObserver:****************
DigitObservser: 10
GraphicObserver:**********
DigitObservser: 45
GraphicObserver:*********************************************
DigitObservser: 1
GraphicObserver:*
DigitObservser: 36
GraphicObserver:************************************
DigitObservser: 45
GraphicObserver:*********************************************
■ 샘플 프로그램에 대해 자세히 알아보기
Git 저장소에도 비슷한 코드가 있습니다.
htps : // 기주 b. 이 m / 싹 / s dy _ f_로 し ん _ 파 rn / t ree /
.
├── Main.py
└── observer
├── __init__.py
├── generator.py
└── observer.py
(1) Subject(피험자)의 역할
Subject
역은, 「관찰되는 측」을 나타냅니다. Subject
역할은 관찰자 Observer
역할을 등록하는 메소드와 삭제하는 메소드를 가지고 있습니다. 또, 「현재의 상태를 취득하는」메소드도 선언되고 있습니다.샘플 프로그램에서는,
NumberGenerator
클래스가, 이 역할을 노력합니다.observer/generator.py
import random
from abc import ABCMeta, abstractmethod
class NumberGenerator(metaclass=ABCMeta):
def __init__(self):
self.__observers = []
def addObserver(self, observer):
self.__observers.append(observer)
def deleteObserver(self, observer):
self.__observers.remove(observer)
def notifyObserver(self):
for o in self.__observers:
o.update(self)
@abstractmethod
def getNumber(self):
pass
@abstractmethod
def execute(self):
pass
(2) ConcreteSubject(구체적인 피험자)의 역할
ConcreteSubject
역은, 구체적인 「관찰되는 측」을 표현하는 역입니다. 상태가 변경되면, 그것이 등록되어 있다 Observer
역에 전합니다.샘플 프로그램에서는,
RandomNumberGenerator
클래스가, 이 역할을 노력합니다.observer/generator.py
class RandomNumberGenerator(NumberGenerator):
def __init__(self):
self.__number = 0
super(RandomNumberGenerator, self).__init__()
def getNumber(self):
return self.__number
def execute(self):
for _ in range(20):
self.__number = random.randint(0, 49)
self.notifyObserver()
(3) Observer (관찰자)의 역할
Observer
역은, Subject
역으로부터 「상태가 변화했습니다」라고 가르쳐 주는 역입니다. 이를 위한 메소드가 update
입니다.샘플 프로그램에서는,
Observer
클래스가, 이 역할을 노력합니다.observer/observer.py
import time
from abc import ABCMeta, abstractmethod
class Observer(metaclass=ABCMeta):
@abstractmethod
def update(self, generator):
pass
(4) ConcreteObserver (구체적인 관찰자)의 역할
ConcreteObserver
역할은 구체적인 Observer
입니다. update
메소드가 불려 가면(자), 그 메소드안에서 Subject
역의 현재 상태를 취득합니다.샘플 프로그램에서는,
DigitObserver
클래스와 GraphObserver
클래스가, 이 역할을 노력합니다.observer/observer.py
class DigitObserver(Observer):
def update(self, generator):
print("DigitObservser: {0}".format(generator.getNumber()))
time.sleep(0.1)
class GraphObserver(Observer):
def update(self, generator):
print("GraphicObserver:", end='')
count = generator.getNumber()
for _ in range(count):
print('*', end='')
print("")
time.sleep(0.1)
(5) Client(의뢰인)의 역할
샘플 프로그램에서는,
startMain
메소드가, 이 역할을 노력합니다.Main.py
from observer.observer import DigitObserver, GraphObserver
from observer.generator import RandomNumberGenerator
def startMain():
generator = RandomNumberGenerator()
observer1 = DigitObserver()
observer2 = GraphObserver()
generator.addObserver(observer1)
generator.addObserver(observer2)
generator.execute()
if __name__ == '__main__':
startMain()
■ 참고 URL
Reference
이 문제에 관하여(파이썬에서 디자인 패턴 "Observer"를 배우십시오.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/ttsubo/items/34690c8e9351f5b2e989텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)