舉例講解Python設計模式編程中的訪問者與觀察者模式

來源:互聯網
上載者:User
訪問者模式
我覺得Visitor模式是在補修改已有程式結構前提下,通過添加額外的訪問者完成對代碼功能的拓展 為什麼這樣用?當你的類層次較多,在某層結構中增加新的方法,要是在基類上面添加或者變更,可能破壞原來的設計, 有相容問題,所以只在需要的類上面動態添加。

python的例子
這裡是個構建車的例子,每個組件都有一個accept的方法接受我上面說的所謂'訪問者',而這個訪問者 以參數的方式傳進來,但是其實他是一個含有一些功能的類的執行個體,它擁有很多個visit開頭的方法對應不同的組件。 這樣就不需要修改這些組件,而只是修改我們的訪問者類的相關部分。

# 輪子,引擎, 車身這些定義好了都不需要變動class Wheel:  def __init__(self, name):    self.name = name  def accept(self, visitor):    # 每個visitor是同樣的,但是其中的方法是不一樣的,比如這裡是visitWheel,    # 然後傳入了self,想想?他其實想做什麼就能做什麼    visitor.visitWheel(self)class Engine:  def accept(self, visitor):    visitor.visitEngine(self)class Body:  def accept(self, visitor):    visitor.visitBody(self)# 我們要組合成車class Car:  def __init__(self):    self.engine = Engine()    self.body  = Body()    self.wheels = [ Wheel("front left"), Wheel("front right"),            Wheel("back left") , Wheel("back right") ]  # 這個也不需要在動,他只是上面組件的組合,只是做了屬性的委託  def accept(self,visitor):    visitor.visitCar(self)    self.engine.accept(visitor)    self.body.accept(visitor)    for wheel in self.wheels:      wheel.accept(visitor)# 這個才是我們的訪問者,每次的修改都在這裡面class PrintVisitor:  def visitWheel(self, wheel):    print "Visiting "+wheel.name+" wheel"  def visitEngine(self, engine):    print "Visiting engine"  def visitBody(self, body):    print "Visiting body"  def visitCar(self, car):    print "Visiting car"if __name__ == '__main__':  car = Car()  visitor = PrintVisitor()  car.accept(visitor)


觀察者模式
當我們希望一個對象的狀態發生變化,那麼依賴與它的所有對象都能相應變化(獲得通知),那麼就可以用到Observer模式, 其中的這些依賴對象就是觀察者的對象,那個要發生變化的對象就是所謂'觀察者'

python的例子

# 這個是觀察者基類class Subject(object):  def __init__(self):    self._observers = []  # 添加依賴的對象  def attach(self, observer):    if not observer in self._observers:      self._observers.append(observer)  # 取消添加  def detach(self, observer):    try:      self._observers.remove(observer)    except ValueError:      pass  # 這裡只是通知上面註冊的依賴對象新的變化  def notify(self, modifier=None):    for observer in self._observers:      # 可以設定過濾條件,對不符合過濾條件的更新      if modifier != observer:        observer.update(self)# 觀察者類class Data(Subject):  def __init__(self, name=''):    super(Data, self).__init__()    self.name = name    self._data = 0  # python2.6新增的寫法,擷取屬性為property,設定屬性為(假設屬性名稱字為x)@x.setter,刪除為@x.deleter  @property  def data(self):    return self._data  @data.setter  def data(self, value):    self._data = value    self.notify()# 這裡有2個被觀察者,也就是依賴的對象,每次Data有改變,這2個view都會變動class HexViewer(object):  def update(self, subject):    print 'HexViewer: Subject %s has data 0x%x' % (subject.name, subject.data)class DecimalViewer(object):  def update(self, subject):    print 'DecimalViewer: Subject %s has data %d' % (subject.name, subject.data)if __name__ == '__main__':  data1 = Data('Data 1')  data2 = Data('Data 2')  view1 = DecimalViewer()  view2 = HexViewer()  data1.attach(view1)  data1.attach(view2)  data2.attach(view2)  data2.attach(view1)  print "Setting Data 1 = 10"  data1.data = 10  print "Setting Data 2 = 15"  data2.data = 15  print "Setting Data 1 = 3"  data1.data = 3  print "Setting Data 2 = 5"  data2.data = 5  print "Update data1's view2 Because view1 is be filtered"  data1.notify(modifier=view1)   print "Detach HexViewer from data1 and data2."  data1.detach(view2)  data2.detach(view2)  print "Setting Data 1 = 10"  data1.data = 10  print "Setting Data 2 = 15"  data2.data = 15
  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.