ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 옵저버 패턴(observer pattern)
    Python/이것저것 파이썬 2021. 10. 23. 12:35
    반응형
    # observer pattern 1
    
    class Subscriber:
        def __init__(self, name):
            self.name = name
    
        def update(self, message):
            print(f'{self.name}, {message}')
    
    
    class Publisher:
        def __init__(self):
            self.subscribers = set()
    
        def register(self, person):
            self.subscribers.add(person)
    
        def unregister(self, person):
            self.subscribers.remove(person)
    
        def dispatch(self, message):
            for subscriber in self.subscribers:
                subscriber.update(message)
    
    
    p = Publisher()
    
    kim = Subscriber('Kim')
    lee = Subscriber('Lee')
    jung = Subscriber('Jung')
    
    p.register(kim)
    p.register(lee)
    p.register(jung)
    
    p.dispatch('점심시간입니다.')
    p.unregister(lee)
    p.dispatch('퇴근시간입니다.')

     

    다양한 독자 그룹을 가질 경우...

    # observer pattern 2
    
    class SubscriberGroupA:
        def __init__(self, name):
            self.name = name
    
        def update(self, message):
            print(f'{self.name}, {message}')
    
    
    class SubscriberGroupB:
        def __init__(self, name):
            self.name = name
    
        def receive(self, message):
            print(f'{self.name}, {message}')
    
    
    class Publisher:
        def __init__(self):
            self.subscribers = dict()
    
        def register(self, person, callback=None):
            if callback is None:
                callback = getattr(person, 'update')
            self.subscribers[person] = callback
    
        def unregister(self, person):
            del self.subscribers[person]
    
        def dispatch(self, message):
            for subscriber, callback in self.subscribers.items():
                callback(message)
    
    
    p = Publisher()
    
    kim = SubscriberGroupA('Kim')
    lee = SubscriberGroupB('Lee')
    jung = SubscriberGroupA('Jung')
    
    p.register(kim, kim.update)
    p.register(lee, lee.receive)
    p.register(jung)
    
    p.dispatch('점심시간입니다.')
    p.unregister(lee)
    p.dispatch('퇴근시간입니다.')

    getattr(object, 'name')은 object라는 오브젝트 내부의 name이라는 멤버를 반환한다.
    '문자열로 멤버를 부를 수 있다.'는 이야기
    일반적으로 getattr.name 하면 될 일이기에 평소에 쓸일이 없지만, 
    이놈 저놈 불러야할 때는 아주 유용하다. 

    이벤트 위주로

    # observer pattern 3
    
    class Subscriber:
        def __init__(self, name):
            self.name = name
    
        def update(self, message):
            print(f'{self.name}, {message}')
    
    
    class Publisher:
        def __init__(self, events):
            self.subscribers = {event: dict() for event in events}
    
        def get_subscribers(self, event):
            return self.subscribers[event]
    
        def register(self, event, person, callback=None):
            if callback is None:
                callback = getattr(person, 'update')
            self.get_subscribers(event)[person] = callback
    
        def unregister(self, event, person):
            del self.get_subscribers(event)[person]
    
        def dispatch(self, event, message):
            for subscriber, callback in self.get_subscribers(event).items():
                callback(message)
    
    
    p = Publisher(('점심', '퇴근'))
    
    kim = Subscriber('Kim')
    lee = Subscriber('Lee')
    jung = Subscriber('Jung')
    
    p.register('점심', kim)
    p.register('퇴근', lee)
    p.register('점심', jung)
    
    p.dispatch('점심', '점심시간입니다.')
    p.dispatch('퇴근', '퇴근시간입니다.')

     

    이런 조합도....

    # observer pattern 4
    
    class SubscriberGroupA:
        def __init__(self, name):
            self.name = name
    
        def update(self, message):
            print(f'{self.name}, {message}')
    
    
    class SubscriberGroupB:
        def __init__(self, name):
            self.name = name
    
        def receive(self, message):
            print(f'{self.name}, {message}')
    
    
    class Publisher:
        def __init__(self, events):
            self.subscribers = {event: dict() for event in events}
    
        def get_subscribers(self, event):
            return self.subscribers[event]
    
        def register(self, event, person, callback=None):
            if callback is None:
                callback = getattr(person, 'update')
            self.get_subscribers(event)[person] = callback
    
        def unregister(self, event, person):
            del self.get_subscribers(event)[person]
    
        def dispatch(self, event, message):
            for subscriber, callback in self.get_subscribers(event).items():
                callback(message)
    
    
    p = Publisher(('점심', '퇴근'))
    
    kim = SubscriberGroupA('Kim')
    lee = SubscriberGroupB('Lee')
    jung = SubscriberGroupA('Jung')
    
    p.register('점심', kim)
    p.register('퇴근', lee, lee.receive)
    p.register('점심', jung)
    
    p.dispatch('점심', '점심시간입니다.')
    p.dispatch('퇴근', '퇴근시간입니다.')
    반응형
Designed by Tistory.