行为型模式用于简化类之间的交互。这里提供了三个例子:观察者(observer)、访问者(visitor)、模板(template)
1.观察者
# _*_ coding=utf-8 _*_class Event(object): _observers = [] def __init__(self, subject): self.subject = subject @classmethod def register(cls, observer): if observer not in cls._observers: cls._observers.append(observer) @classmethod def unregister(cls, observer): if observer in cls._observers: cls._observers.remove(observer) @classmethod def notify(cls, subject): event = cls(subject) for observer in cls._observers: observer(event)class WriteEvent(Event): def __repr__(self): return 'WriteEvent'def log(event): print '%s was written' % event.subjectWriteEvent.register(log)class AnotherObserver(object): def __call__(self, event): print 'Yeah %s told me!' % eventWriteEvent.register(AnotherObserver())WriteEvent.notify("a given file")
2.访问者
# _*_ coding=utf-8 _*_
class vlist(list): def accept(self, visitor): visitor.visit_list(self)class vdict(dict): def accept(self, visitor): visitor.visit_dict(self)class Printer(object): def visit_list(self, ob): print 'list cintent' print str(ob) def visit_dict(self, ob): print 'dict keys: %s' % ','.join(ob.keys())# a_list = vlist([1, 2, 5])# a_list.accept(Printer())# a_dict = vdict({'one': 1, 'two': 2, 'three': 3})# a_dict.accept(Printer())# def visit(visited, visitor):# cls = visited.__class__.__name__# meth = 'visit_%s' % cls# method = getattr(visitor, meth, None)# if method is not None:# method(visited)## visit([1, 2, 5], Printer())# visit({'one': 1, 'two': 2, 'three': 3}, Printer())import osdef visit(directory, visitor): for root, dirs, files in os.walk(directory): for file in files: ext = os.path.splitext(file)[-1][1:] if hasattr(visitor, ext): getattr(visitor, ext)(file)class FileReader(object): def pdf(self, file): print 'processing %s' % filewalker = visit("/Users/lucas/Downloads", FileReader())
3.模板
# _*_ coding=utf-8 _*_from itertools import groupbyclass Indexer(object): def process(self, text): text = self._normalize_text(text) words = self._split_text(text) words = self._remove_stop_words(words) stemmed_words = self._stem_words(words) return self._frequency(stemmed_words) def _normalize_text(self, text): return text.lower().strip() def _split_text(self, text): return text.split() def _remove_stop_words(self, words): raise NotImplementedError def _stem_words(self, words): raise NotImplementedError def _frequency(self, words): counts = {} for word in words: counts[words] = counts.get(word, 0) + 1 return countsclass BasicIndexer(Indexer): _stop_words = ('he', 'she', 'is', 'and', 'or') def _remove_stop_words(self, words): return [word for word in words if word not in self._stop_words] def _stem_words(self, words): return [(len(word) > 2 and word.rstrip('aeiouy') or word) for word in words] def _frequency(self, words): freq = {} for word in words: freq[word] = freq.get(word, 0) + 1 return freqindexer = BasicIndexer()print indexer.process(('My Tailor is rich and he is also my friend'))