from cppy.cp_util import * ''' 订阅者 = 注册者 = 观察者 注册回调的一个变体 要点是:中心化、统一化 为了简化消息订阅可能形成的复杂性, 提供一个中心消息管理器统一负责消息的订阅和回调 各个功能组件只是完成自己的功能, 在中心管理器上订阅消息挂到自己响应的处理函数上 总结,相比较的改变: - 注册的时候,通过提供一个类型字段标识不同消息 - 其它实体不做注册和做回调,统一这两个功能到一个中心单元 这是一个示例性质的原型,具体分布式环境下需要调整 ''' from collections import defaultdict ################################################# # Event Manager ################################################# class EventManager: def __init__(self): self._subs = defaultdict(list) def subscribe(self, event_type, handler): self._subs[event_type].append(handler) def publish(self, event): event_type = event[0] for handle in self._subs.get(event_type, []): handle(event) ################################################# # Application Entities ################################################# class DataStorage: def __init__(self, event_manager): self._event_manager = event_manager self._event_manager.subscribe('load', self._load) self._event_manager.subscribe('start', self.produce_words) def _load(self, event): self._data = extract_file_words( event[1] ) def produce_words(self, _): for word in self._data: self._event_manager.publish(('word', word )) self._event_manager.publish(('eof', None)) class StopWordFilter: def __init__(self, event_manager): self._event_manager = event_manager self._event_manager.subscribe('load', self.load_stop_words) self._event_manager.subscribe('word', self.filter_word) self._stop_words = set() def load_stop_words(self, _ ): self._stop_words = set( get_stopwords() ) def filter_word(self, event): word = event[1] if word not in self._stop_words: self._event_manager.publish(('valid_word', word)) class WordFrequencyCounter: def __init__(self, event_manager): self._event_manager = event_manager self._event_manager.subscribe('valid_word', self.count_word) self._event_manager.subscribe('print', self.print_freqs) self._word_freqs = {} def count_word(self, event): word = event[1] self._word_freqs[word] = self._word_freqs.get(word, 0) + 1 def print_freqs(self, _ ): print_word_freqs ( sort_dict (self._word_freqs) ) class WordFrequencyApp: def __init__(self, event_manager): self._event_manager = event_manager self._event_manager.subscribe('run', self.start_application) self._event_manager.subscribe('eof', self.stop_application) def start_application(self, event): path_to_file = event[1] self._event_manager.publish(('load', path_to_file)) self._event_manager.publish(('start', )) def stop_application(self, _ ): self._event_manager.publish(('print', )) def main(): event_manager = EventManager() DataStorage( event_manager ) StopWordFilter( event_manager ) WordFrequencyCounter( event_manager ) WordFrequencyApp( event_manager ) event_manager.publish(('run', testfilepath )) if __name__ == "__main__": main()