第三個模塊。
observer.py
#!/usr/bin/env python# encoding: utf-8"""觀察者模式定義類一種一對多的依賴關系, 讓多個觀察者對象同時監聽某一個主題對象, 這個主題對象在發生變化時, 會通知所有觀察者對象, 使它們能夠自動干呢更新自己- 適用: 當一個對象的改變需要同時改變其他對象時- 解耦合, 讓耦合的雙方依賴于抽象, 而不是依賴于具體"""from abc import ABCMeta, abstractmethodclass Subject(object): """ 把所有對觀察者對象的引用保存在一個聚集里 每個主題都可以有任意數量的觀察者. 抽象主題提供了接口增加/刪除觀察者對象 """ def __init__(self): self.__observers = [] def attach(self, observer): self.__observers.append(observer) def detach(self, observer): self.__observers.remove(observer) def notify(self): for o in self.__observers: o.update()class ConcreteSubject(Subject): """ 具體主題, 將有關狀態存入具體的觀察者對象 在具體主題的內部狀態改變時, 給所有登記過的觀察者發出通知 """ @PRoperty def status(self): return self.__status @status.setter def status(self, value): self.__status = valueclass Observer(object): """ 抽象觀察者, 位所有具體觀察者定義接口, 在得到主題的通知時更新自己 """ __metaclass__ = ABCMeta @abstractmethod def update(self): passclass ConcreteObserver(Observer): """ 具體觀察者, 實現抽象觀察者鎖要求的更新接口 以使本身的狀態與主題的狀態相協調 """ def __init__(self, subject, name): self.subject = subject self.name = name self.objserver_staus = None def update(self): self.objserver_staus = self.subject.status print "the observer: %s status change to %s" % (self.name , self.objserver_staus)if __name__ == '__main__': s = ConcreteSubject() s.attach(ConcreteObserver(s, "X")) s.attach(ConcreteObserver(s, "Y")) s.attach(ConcreteObserver(s, "Z")) s.status = "A" s.notify() s.status = "B" s.notify()abstract.py#!/usr/bin/env python# encoding: utf-8"""模板方法模式定義一個操作中的算法的股價, 而將一些步驟的實現延遲到子類中這樣, 可以使得子類可以不改變一個算法的結構即可重定義該算法的某些特定步驟- 把不變行為放到超類, 去除子類中的重復代碼- 提供了一個很好地代碼復用平臺"""from abc import ABCMeta, abstractmethodclass AbstractClass(object): """ 實現了一個模板方法, 定義了算法的掛架 """ __metaclass__ = ABCMeta def say_hello(self): print "begin..." self.hello() self.world() print "end..." @abstractmethod def hello(self): pass @abstractmethod def world(self): passclass ConcreteClass(AbstractClass): """ 實現了特定的步驟 """ def hello(self): print "hello" def world(self): print "world"if __name__ == '__main__': c = ConcreteClass() c.say_hello()command.py#!/usr/bin/env python# encoding: utf-8"""命令模式講一個請求封裝為一個對象, 從而使你可用不同的請求對客戶進行參數化對請求排隊或記錄請求日志, 以及支持可撤銷操作- 比較容易設計一個命令隊列- 在需要情況下, 可以將命令計入日志- 允許接受請求的一方決定是否要否決請求- 可以容易的實現對請求的撤銷和崇左- 由于加緊新的具體命令類不影響其他類, 可以很容易新增- 把請求一個操作的對象與指導怎么執行一個操作的對象分隔開"""from abc import ABCMeta, abstractmethodclass Command(object): """ 聲明執行操作的接口 """ __metaclass__ = ABCMeta def __init__(self, receiver): self.receiver = receiver @abstractmethod def execute(self): passclass ConcreteCommand(Command): """ 將一個接受著對象綁定于一個動作, 調用接收者相應的操作 """ def execute(self): self.receiver.action()class Invoker(object): @property def command(self): return self.__command @command.setter def command(self, value): self.__command = value def execute_command(self): self.__command.execute()class Receiver(object): def action(self): print "execute command"if __name__ == '__main__': r = Receiver() cmd = ConcreteCommand(r) invoker = Invoker() invoker.command = cmd invoker.execute_command()state.py#!/usr/bin/env python# encoding: utf-8"""狀態模式當一個對象的內在狀態改變時, 允許改變其行為. 這個對象看起來更像是改變了其類- 解決: 當控制一個對象狀態轉換的條件表達式過于復雜的情況, 把狀態的判斷邏輯轉移到表示不同狀態的一系列類中, 可以把復雜的判斷邏輯簡單化- 好處: 將與特定狀態相關的行為局部化, 并且將不同狀態的行為分割開來- 通過定義新的子類, 可以很容易地增加新的狀態和轉換- 消除龐大的條件分支語句, 減少相互間的依賴, 把各種狀態轉移邏輯分布到了State的子類之間- 適用: 當一個對象的行為取決于它的狀態, 并且它必需在運行時刻根據狀態改變其行為時, 使用狀態模式"""from abc import ABCMeta, abstractmethodclass State(object): """ 抽象狀態類, 定義一個接口以封裝與Context的一個特定狀態相關的行為 """ __metaclass__ = ABCMeta @abstractmethod def handle(self, context): passclass ConcreteStateA(State): def handle(self, context): """ 設定下一個狀態是 """ context.state = ConcreteStateB()class ConcreteStateB(State): def handle(self, context): """ 設定下一個狀態是 """ context.state = ConcreteStateA()class Context(object): """ 維護一個ConcreteState子類的實例, 這個實例定義當前的狀態 """ def __init__(self, state): self.__state = state @property def state(self): return self.__state @state.setter def state(self, value): print "current status:", value.__class__.__name__ self.__state = value def request(self): self.__state.handle(self)if __name__ == '__main__': c = Context(ConcreteStateA()) c.request() c.request() c.request() c.request()chain_of_responsibility.py#!/usr/bin/env python# encoding: utf-8"""責任鏈模式使多個對象都以機會處理請求, 從而避免請求的發送者和接受者之間的耦合關系將這個對象連成一條鏈, 沿著這條鏈傳遞請求, 直到有一個對象處理它為止- 可以隨意增加或修改處理一個請求的鏈式結構"""from abc import ABCMeta, abstractmethodclass Handler(object): """ 定義一個處理請求的接口 """ __metaclass__ = ABCMeta def __init__(self): self.__successor = None @property def successor(self): return self.__successor @successor.setter def successor(self, value): self.__successor = value @abstractmethod def handle_request(self, request): passclass ConcreteHandlerA(Handler): """ 具體處理類, 處理它所負責的請求 如果可以處理該請求, 處理之, 否則轉給后繼者 """ def handle_request(self, request): if 0 <= request < 10: print "%s process %s" % (self.__class__.__name__, request) else: self.successor.handle_request(request)class ConcreteHandlerB(Handler): """ 具體處理類, 處理它所負責的請求 如果可以處理該請求, 處理之, 否則轉給后繼者 """ def handle_request(self, request): if 10 <= request < 20: print "%s process %s" % (self.__class__.__name__, request) else: self.successor.handle_request(request)class ConcreteHandlerC(Handler): """ 具體處理類, 處理它所負責的請求 如果可以處理該請求, 處理之, 否則轉給后繼者 """ def handle_request(self, request): if 20 <= request < 30: print "%s process %s" % (self.__class__.__name__, request) else: self.successor.handle_request(request)if __name__ == '__main__': h1 = ConcreteHandlerA() h2 = ConcreteHandlerB() h3 = ConcreteHandlerC() h1.successor = h2 h2.successor = h3 for req in [2, 14, 22]: print req h1.handle_request(req)interpreter.py#!/usr/bin/env python# encoding: utf-8"""解釋器模式給定一個語言, 定義他的文法的一種表示, 并定義一個解釋器, 這個解釋器使用該表示來解釋語言中的句子- 解決: 如果一種特定類型問題發生的頻率足夠高, 那么可能就值得將該問題的各個實例表述為一個簡單語言中的句子, 這樣就可以構建一個解釋器, 該解釋其通過解釋這些句子來解決該問題- 適用: 當有一個語言需要解釋執行, 并且你可以將該語言中的句子表示為一個抽象語法樹時- 好處: 容易改變和擴展文法- 不足: 需要為文法中的每一條規則至少定義一個類, 可能難以維護和管理"""from abc import ABCMeta, abstractmethodclass AbstractExpression(object): """ 抽象表達式, 聲明一個抽象的解釋操作 這個接口被抽象語法書中的所有節點所共享 """ __metaclass__ = ABCMeta @abstractmethod def interpret(self, context): passclass TerminalExpression(AbstractExpression): """ 終結符表達式 實現與文法中的終結符相關聯的解釋操作 """ def interpret(self, context): print "terminal"class NoterminalExpression(AbstractExpression): """ 非終結符表達式 為文法中的非終結符實現解釋操作, 對文法中每一條規則R1/R2...Rn都需要一個具體的非終結符表達式 """ def interpret(self, context): print "no terminal"class Context(object): """ 包含解釋器之外的一些全局信息 """ def __init__(self, input, output): self.__input = input self.__output = output @property def input(self): return self.__input @input.setter def input(self, value): self.__input = value @property def output(self): return self.__output @output.setter def output(self, value): self.__output = valueif __name__ == '__main__': context = Context("in", "out") l = [] l.append(TerminalExpression()) l.append(TerminalExpression()) l.append(NoterminalExpression()) for i in l: i.interpret(context)mediator.py#!/usr/bin/env python# encoding: utf-8"""中介者模式用一個中介對象來封裝一系列的對象交互中介者使各對象不需要顯示的相互引用, 從而使耦合松散, 可以獨立地改變他們之間的交互- 多對多交互- 把對象如何寫作進行了抽象"""from abc import ABCMeta, abstractmethodclass Mediator(object): """ 抽象中介者, 定義了同事對象到中介者對象的接口 """ __metaclass__ = ABCMeta @abstractmethod def send(self, msg, colleague): passclass ConcreteMediator(Mediator): """ 具體中介者對象, 實現抽象類的方法 需要知道所有具體的同事類, 并從具體的同事類接收消息, 想具體同事對象發出命令 """ @property def colleague1(self): return self.__colleague1 @colleague1.setter def colleague1(self, value): self.__colleague1 = value @property def colleague2(self): return self.__colleague2 @colleague2.setter def colleague2(self, value): self.__colleague2 = value def send(self, msg, colleague): if colleague == self.__colleague1: self.__colleague2.notify(msg) else: self.__colleague1.notify(msg)class Colleague(object): """ 抽象同事類 """ __metaclass__ = ABCMeta def __init__(self, mediator): self.__mediator = mediator @property def mediator(self): return self.__mediator @abstractmethod def send(self, message): pass @abstractmethod def notify(self, message): passclass ConcreteColleague1(Colleague): def send(self, message): self.mediator.send(message, self) def notify(self, message): print "colleageu 1 get message: ", messageclass ConcreteColleague2(Colleague): def send(self, message): self.mediator.send(message, self) def notify(self, message): print "colleageu 2 get message: ", messageif __name__ == '__main__': m = ConcreteMediator() c1 = ConcreteColleague1(m) c2 = ConcreteColleague2(m) m.colleague1 = c1 m.colleague2 = c2 c1.send("hello, I am C1") c2.send("Hey, I am C2")visitor.py#!/usr/bin/env python# encoding: utf-8"""訪問者模式標識一個作用于某對象結構中的各元素的操作可以使你在不改變各元素類的前提下定義作用于這些元素的新操作- 適用于數據結構相對穩定的系統, 把數據結構和作用于結構上的操作之間的耦合解脫開, 是的操作集合可以相對自由地演化- 目的是: 把處理從數據結構分離出來, 有比較穩定的數據結構, 又有易于變化的算法- 優點: 增加新的操作很容易, 等同于增加一個新的訪問者"""from abc import ABCMeta, abstractmethodclass Visitor(object): """ 為該對象結構中concreteelement的每一個類聲明一個visit操作 """ __metaclass__ = ABCMeta @abstractmethod def visitor_concrete_element_a(self, concrete_element_a): pass @abstractmethod def visitor_concrete_element_b(self, concrete_element_b): passclass ConcreteVisitor1(Visitor): """ 具體訪問者, 實現每個聲明的操作 每個操作實現算法的一部分, 而該算法片段乃是對應于結構中對象的類 """ def visitor_concrete_element_a(self, concrete_element_a): print "%s visit %s" % (self.__class__.__name__, concrete_element_a.__class__.__name__) def visitor_concrete_element_b(self, concrete_element_b): print "%s visit %s" % (self.__class__.__name__, concrete_element_b.__class__.__name__)class ConcreteVisitor2(Visitor): """ 具體訪問者, 實現每個聲明的操作 每個操作實現算法的一部分, 而該算法片段乃是對應于結構中對象的類 """ def visitor_concrete_element_a(self, concrete_element_a): print "%s visit %s" % (self.__class__.__name__, concrete_element_a.__class__.__name__) def visitor_concrete_element_b(self, concrete_element_b): print "%s visit %s" % (self.__class__.__name__, concrete_element_b.__class__.__name__)class Element(object): """ 定義一個accept操作, 以一個訪問者為參數 """ __metaclass__ = ABCMeta @abstractmethod def accept(self, visitor): passclass ConcreteElementA(Element): """ 具體元素, 實現accept操作 """ def accept(self, visitor): visitor.visitor_concrete_element_a(self)class ConcreteElementB(Element): """ 具體元素, 實現accept操作 """ def accept(self, visitor): visitor.visitor_concrete_element_b(self)class ObjectStructure(object): """ 能枚舉它的元素, 可以提供一個高層的接口以允許訪問者訪問它的元素 """ def __init__(self): self.__elements = [] def attach(self, element): self.__elements.append(element) def detach(self, element): self.__element.remove(element) def accept(self, visitor): for e in self.__elements: e.accept(visitor)if __name__ == '__main__': os = ObjectStructure() os.attach(ConcreteElementA()) os.attach(ConcreteElementB()) v1 = ConcreteVisitor1() os.accept(v1) v2 = ConcreteVisitor2() os.accept(v2)strategy.py#!/usr/bin/env python# encoding: utf-8"""策略模式它定義了算法家族, 分別封裝起來, 讓他們之間可以互相替換, 此模式讓算法的變化, 不會影響到使用算法的客戶- 策略模式是一種定義一系列算法的方法, 從概念上來講, 所有算法完成的都是相同的工作, 只是實現不同, 它可以以相同的方式調用所有的算法, 減少各種算法與算法類之間的耦合- 策略模式的Strategy類層次位Context定義了一系列的可供重用的算法或行為, 繼承有助于析取出這些算法中的公用功能- 優點: 簡化了單元測試, 每個算法有自己的類, 可以通過自己的接口單獨測試- 解決: 不同行為堆砌在同一個類中, 很難避免使用條件語句, 通過Strategy消除之- 作用: 封裝算法/業務規則等"""from abc import ABCMeta, abstractmethodclass Strategy(object): """ 策略類, 定義所有支持的算法的公共接口 """ __metaclass__ = ABCMeta @abstractmethod def calculate(self): passclass StrategyA(Strategy): """ 具體策略類, 封裝了具體的算法和行為 """ def calculate(self): print "calculate A"class StrategyB(Strategy): """ 具體策略類, 封裝了具體的算法和行為 """ def calculate(self): print "calculate B"class Context(object): """ 上下文, 維護一個對strategy對象的引用 """ def __init__(self, strategy): self.__strategy = strategy def do_calculate(self): self.__strategy.calculate()if __name__ == '__main__': c1 = Context(StrategyA()) c1.do_calculate() c2 = Context(StrategyB()) c2.do_calculate()memento.py#!/usr/bin/env python# encoding: utf-8"""備忘錄在不破壞封裝性的前提下, 捕獲一個對象的內部狀態, 并在該對象之外保存這個狀態這樣以后可以將該對象恢復到原先保存的狀態- 將要保存的細節封裝到memento中- 比較適合功能比較復雜, 需要維護或記錄屬性的歷史類, 或者需要保存部分屬性- 例如: 保存歷史命令, 并執行撤銷操作- 備忘錄可以把復雜的對象內部信息對其他對象屏蔽起來"""class Originator(object): """ 創建一個備忘錄Memento, 用以記錄當前時刻的內部狀態, 并可以使用備忘錄恢復內部狀態 """ def __init__(self, state): self.__state = state @property def state(self): return self.__state @state.setter def state(self, value): self.__state = value def create_memento(self): return Memento(self.__state) def set_memento(self, memento): self.__state = memento.state def show(self): print "State:", self.__stateclass Memento(object): """ 負責存儲Originator的內部狀態, 并可以防止除Originator以外的其他對象訪問 """ def __init__(self, state): self.__state = state @property def state(self): return self.__stateclass Caretaker(object): """ 負責保存好備忘錄Memento """ def __init__(self): self.__memento = None @property def memento(self): return self.__memento @memento.setter def memento(self, value): self.__memento = valueif __name__ == '__main__': o = Originator("init") o.show() o.state = "begin" o.show() mem = o.create_memento() # save it c = Caretaker() c.memento = mem o.state = "change" o.show() # recover o.set_memento(c.memento) o.show()iterator.py#!/usr/bin/env python# encoding: utf-8"""迭代器模式提供一種方法順序地訪問一個聚合對象中的各個元素, 而又不暴露改對象的內部表示- 無差別遍歷聚合對象- 需要對聚集進行多種方式遍歷時- 分離了集合對象的遍歷行為, 做到不暴露集合內部結構, 又可以讓外部代碼透明的訪問集合內部的數據"""# 不考慮默認的迭代器from abc import ABCMeta, abstractmethodclass Iterator(object): """ 迭代抽象類 定義迭代器抽象方法 """ __metaclass__ = ABCMeta @abstractmethod def first(self): pass @abstractmethod def next(self): pass @abstractmethod def is_done(self): pass @abstractmethod def current_item(self): passclass ConcreteIterator(Iterator): def __init__(self, aggregate): self.__aggregate = aggregate self.current = 0 def first(self): return self.__aggregate[0] def next(self): result = None self.current += 1 if self.current < len(self.__aggregate): result = self.__aggregate[self.current] return result def is_done(self): return self.current >= len(self.__aggregate) def current_item(self): return self.__aggregate[self.current]if __name__ == '__main__': aggregate = [0] * 3 aggregate[0] = 'a' aggregate[1] = 'b' aggregate[2] = 'c' it = ConcreteIterator(aggregate) i = it.first() while not it.is_done(): print "current:", it.current_item() it.next()
新聞熱點
疑難解答