Pythonによるデザインパターン【Observer】-本日のニュースをお届けします-
参考
@kidachi1さんの記事のRubyの記事のソースコードをpythonに書き換えてます。
https://qiita.com/kidach1/items/ce18d2a926c558159689
@kidachi1さん、いつもありがとうございます。
概要
Rubyによるデザインパターン第5章。
Observer Pattern。
Rubyによるデザインパターン5原則に則って理解する。
この記事はPython
どんなパターンか
あるオブジェクトの状態に関心のあるオブジェクトに、都度通知を送る。
ニュースの発信源(Subject)とニュースの消費者(Observer)間に綺麗なインターフェイスを用意する。
Subject
あるニュースを配信するクラス
Observer
あるニュースを得ることに関心があるクラス
メリット
ニュースの発信者と受信者の間の依存関係を排除する。
問題のあるコード
従業員の給与の変化を経理部門に伝えるシステム
従業員クラス
class Employee:
def __init__(self, name, title, salary, payroll):
self.name = name
self.title = title
self.salary = salary
self.payroll = payroll
def update_salary(self, new_salary):
self.salary = new_salary
self.payroll.update(self)
経理部門クラス
class Payroll:
def __init__(self):
pass
def update(self, changed_employee): # Subjectオブジェクトを受け取る
print ( changed_employee.name + "の給料が" + str(changed_employee.salary) + "ドルに上がりました!" )
クラスの利用
payroll = Payroll()
employee = Employee( "tsuji","leader", 1000, payroll )
employee.update_salary(2000)
#tsujiの給料が2000ドルに上がりました!
問題
class Employee:
def __init__(self, name, title, salary, payroll):
self.name = name
self.title = title
self.salary = salary
self.payroll = payroll
def update_salary(self, new_salary):
self.salary = new_salary
self.payroll.update(self)
class Payroll:
def __init__(self):
pass
def update(self, changed_employee): # Subjectオブジェクトを受け取る
print ( changed_employee.name + "の給料が" + str(changed_employee.salary) + "ドルに上がりました!" )
クラスの利用
payroll = Payroll()
employee = Employee( "tsuji","leader", 1000, payroll )
employee.update_salary(2000)
#tsujiの給料が2000ドルに上がりました!
問題
payroll = Payroll()
employee = Employee( "tsuji","leader", 1000, payroll )
employee.update_salary(2000)
#tsujiの給料が2000ドルに上がりました!
もし経理部門以外にも通知したくなったら?
→今はEmployeeクラスに手を入れる必要がある。
本質的にはEmployeeに対する変更など何もないにも関わらず・・。
そこで、
変化する事項(「従業員の給与の変更」というニュースを誰が受け取るか)を、Employeeオブジェクトから分離する。
→必要なのは、Employeeオブジェクトの変化に関心のあるオブジェクトの一覧。
従業員クラス
class Employee2:
def __init__(self, name, title, salary ):
self.name = name
self.title = title
self.salary = salary
self.observers = []
def add_observer(self, observer):
self.observers.append(observer)
def update_salary(self, new_salary):
self.salary = new_salary
self.notify_observers()
def notify_observers(self):
for observer in self.observers :
observer.update(self)
経理部クラス
class Payroll:
def __init__(self):
pass
def update(self, changed_employee): # Subjectオブジェクトを受け取る
print ( changed_employee.name + "の給料が" + str(changed_employee.salary) + "ドルに上がりました!" )
print ( "経理部門は" + changed_employee.name + "に小切手を切ります!")
税務署員クラス
class Taxman:
def __init__(self):
pass
def update(self, changed_employee): # Subjectオブジェクトを受け取る
print ( changed_employee.name + "の給料が" + str(changed_employee.salary) + "ドルに上がりました!" )
print ( "税務署員は" + changed_employee.name + "に新しい税金請求書を送ります!")
クラスの利用
taxman = Taxman()
payroll = Payroll()
employee2 = Employee2("daisuke","member", 3000)
employee2.add_observer(payroll)
employee2.add_observer(taxman)
employee2.update_salary(4000)
まとめ
class Employee2:
def __init__(self, name, title, salary ):
self.name = name
self.title = title
self.salary = salary
self.observers = []
def add_observer(self, observer):
self.observers.append(observer)
def update_salary(self, new_salary):
self.salary = new_salary
self.notify_observers()
def notify_observers(self):
for observer in self.observers :
observer.update(self)
class Payroll:
def __init__(self):
pass
def update(self, changed_employee): # Subjectオブジェクトを受け取る
print ( changed_employee.name + "の給料が" + str(changed_employee.salary) + "ドルに上がりました!" )
print ( "経理部門は" + changed_employee.name + "に小切手を切ります!")
税務署員クラス
class Taxman:
def __init__(self):
pass
def update(self, changed_employee): # Subjectオブジェクトを受け取る
print ( changed_employee.name + "の給料が" + str(changed_employee.salary) + "ドルに上がりました!" )
print ( "税務署員は" + changed_employee.name + "に新しい税金請求書を送ります!")
クラスの利用
taxman = Taxman()
payroll = Payroll()
employee2 = Employee2("daisuke","member", 3000)
employee2.add_observer(payroll)
employee2.add_observer(taxman)
employee2.update_salary(4000)
まとめ
class Taxman:
def __init__(self):
pass
def update(self, changed_employee): # Subjectオブジェクトを受け取る
print ( changed_employee.name + "の給料が" + str(changed_employee.salary) + "ドルに上がりました!" )
print ( "税務署員は" + changed_employee.name + "に新しい税金請求書を送ります!")
taxman = Taxman()
payroll = Payroll()
employee2 = Employee2("daisuke","member", 3000)
employee2.add_observer(payroll)
employee2.add_observer(taxman)
employee2.update_salary(4000)
まとめ
変わるもの(オブザーバー)と変わらないもの(サブジェクト)を分離して、変化に強い構造へ
Strategyパターンとの比較
形は似ている
Observerパターン:サブジェクトがオブザーバーを呼び出す
Strategyパターン:コンテキストがストラテジを呼び出す
違いは目的
Observerパターン:サブジェクトで発生したイベントをオブザーバーへ通知する
Strategyパターン:コンテキストが、何か特定の処理を行うためにストラテジを呼び出す
Author And Source
この問題について(Pythonによるデザインパターン【Observer】-本日のニュースをお届けします-), 我々は、より多くの情報をここで見つけました https://qiita.com/tsuji-daisuke/items/719a8fc2e4cc7789c1b4著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .