0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Strategy Pattern (移譲) の採用可否基準と実装例

Last updated at Posted at 2021-09-23
関連記事のトップページ
[シリーズ] 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)

image.png

./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

以上.

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?