関連記事のトップページ |
---|
[シリーズ] Python におけるデザインパターンの記録 |
概要
移譲構造 (Strategy Pattern ≒ C言語の関数ポインタ) の「採用可否の基準」と「実装例」.
引用元は下記書籍である.
ただし、内容について細かく記すと書籍の無断転載になるので大まかに記している.
また、コードは Ruby から Python に書き換えている.
引用元情報 | 一言 |
---|---|
書籍 -- Rubyによるデザインパターン (Russ Olsen 著) | 原書(英文) |
GitHub -- 著者 Russ Olsen 氏 |
採用の基準
ここは独断もしくは私の解釈です.
採用基準は次を満すこと.
・基底クラスの仕様に変更が生じる確率ありそうなので "継承" はしたくないが、シーケンス実装は継承させたい
言い換えると次である.
・継承せずに関数ポインタを実現したい
コード例
ファイル構成
.
|-- ex3_vehicle.py
|-- ex5_engine.py
|-- ex6_car_delegation.py
`-- ex6_car_delegation_test.py
クラス図
Vehicle を基底クラスとして採用とし、
全ての乗り物で必ず存在する 重量(weight) のみを保持させる.
他方、乗り物によっては存在しないエンジンは Vehicle から切り離して、
Engine クラスとして別途作成する.
そして、具象クラスの Car から Engine を参照(≒ポインタ)する.
・重量 (weight)
・エンジン稼働 (start_engine)
・エンジン停止 (stop_engine)
./ex3_vehicle.py
「乗り物」を表わす基底クラス Vehicle.
全ての具象クラスで "共通" かつ "仕様変更が発生しない" 情報のみを保持させる.
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
import sys; sys.dont_write_bytecode = True
class Vehicle(object):
def __init__(self, weight):
self.weight = weight #! 重さ
print(f'This car weighs {self.weight}kg')
./ex5_engine.py
エンジン
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
import sys; sys.dont_write_bytecode = True
class Engine:
def start(self):
print('start the engine')
def stop(self):
print('stop the engine')
./ex6_car_delegation.py
具象クラス
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
import sys; sys.dont_write_bytecode = True
from ex3_vehicle import *
from ex5_engine import *
class Car(Vehicle):
def __init__(self, weight):
super().__init__(weight)
self.engine = Engine()
def start_engine(self): #! エンジン稼働
print('start the engine')
def stop_engine(self): #! エンジン停止
print('stop the engine')
def sunday_drive(self):
self.engine.start()
print('cruise out into the country and return')
self.engine.stop()
./ex6_car_delegation_test.py
テストドライバ
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
import sys; sys.dont_write_bytecode = True
import unittest
from ex6_car_delegation import *
class CarWithDelegationTest(unittest.TestCase):
def test_car(self):
c = Car(weight=650)
c.sunday_drive()
実行例
$ python -m unittest ex6_car_delegation_test.py
This car weighs 650kg
start the engine
cruise out into the country and return
stop the engine
.
----------------------------------------------------------------------
Ran 1 test in 0.000s
OK
以上.