"""
觀察者模式:又叫發(fā)布-訂閱模式。
????它定義了一種一對(duì)多的依賴關(guān)系帮坚,讓多個(gè)觀察者對(duì)象同時(shí)鑒定某一個(gè)主題對(duì)象萤晴。這個(gè)主題對(duì)象在狀態(tài)發(fā)生變化時(shí)胀茵,
會(huì)通知所有的觀察者對(duì)象社露,使它們能夠自動(dòng)更新自己。
觀察者模式所做的工作實(shí)際上就是解耦琼娘,根據(jù)“依賴倒轉(zhuǎn)原則”峭弟,讓耦合的雙方都依賴于抽象,而不是依賴于具體脱拼,
從而使得各自的變化都不會(huì)影響另一邊的變化瞒瘸。
實(shí)際場(chǎng)景中存在的問題:現(xiàn)實(shí)中實(shí)際觀察者不一定有實(shí)現(xiàn)觀察者的通知回調(diào)方法。
解決之道:
1熄浓、為其封裝一個(gè)觀察類出來情臭,實(shí)現(xiàn)相應(yīng)的接口。
2赌蔑、修改通知類俯在,讓具體觀察者的Notify函數(shù)直接去調(diào)用相應(yīng)的接口。
"""
class?Subject(object):
????def?__init__(self):
????????self._observers?=?[]
????def?attach(self,?observer):
????????if?observer?not?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=''):
????????Subject.__init__(self)
????????self.name?=?name
????????self._data?=?0
????@property
????def?data(self):
????????return?self._data
????@data.setter
????def?data(self,?value):
????????self._data?=?value
????????self.notify()
class?HexViewer:
????def?update(self,?subject):
????????print('十六進(jìn)制查看器:?主題?%s?有數(shù)據(jù)?0x%x'?%?(subject.name,?subject.data))
class?DecimalViewer:
????def?update(self,?subject):
????????print('十進(jìn)制查看器:?主題?%s?有數(shù)據(jù)?%d'?%
??????????????(subject.name,?subject.data))
#?用法示例...
def?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("設(shè)置數(shù)據(jù)1變量?=?10")
????data1.data?=?10
????print("設(shè)置數(shù)據(jù)2變量?=?15")
????data2.data?=?15
????print("設(shè)置數(shù)據(jù)1變量?=?3")
????data1.data?=?3
????print("設(shè)置數(shù)據(jù)2變量?=?5")
????data2.data?=?5
????print("從data1和data2分離HexViewer娃惯。")
????data1.detach(view2)
????data2.detach(view2)
????print("設(shè)置數(shù)據(jù)1變量?=?10")
????data1.data?=?10
????print("設(shè)置數(shù)據(jù)2變量?=?15")
????data2.data?=?15
if?__name__?==?'__main__':
????main()