Strategyパターン(戦略≒アルゴリズムを切り替えるデザインパターン)をクラス図にまとめる

デザインパターン

デザインパターンの1つであるStrategyパターンについて自分なりにまとめてみました。

Strategyパターンのクラス図

Strategyパターンのクラス図

Strategyパターンの解説

Strategyクラスが抽象クラスで、ここに定義したメソッドをStrategyを継承するStrategy1、Strategy2クラスで実装する。上のクラス図では仮にfuncメソッドとしているが、このメソッドは何でも構わない。

Contextクラスは属性にStrategy型を持つ(strategyとしている)。コンストラクタなどで属性のstrategyにStrategy1,Strategy2をインスタンス化したオブジェクトを代入しておく。Contextオブジェクトのcallメソッドの内部でstrategyのfuncメソッドを呼び出すと、strategyがStrategy1型かStrategy2型かによってどちらかのfuncメソッドが呼び出される。

funcメソッドは仮のEntity型の変数を戻り値として定義している。実際にはEntityクラスの定義が必要だが今回はStrategyパターンとは関係ないのでクラス図には含めていない。Entity1,Entity2はEntityを継承しているクラスだと考えてもらえればよい。

パターンをどういう場合に使うか

例えばファイルアップロードされた場合に、PDFだったらこの処理、エクセルだったら別処理、・・・といったようにファイル形式毎に処理が異なるような場合、Contextクラスでアップロードのリクエストを受け取るとすると、Contextのメソッド内でif文を作りアップロードファイルの形式を判定し、各々の処理を行うことが可能である。が、ファイル形式がもっと増えていった場合、Contextのメソッド内で完結させようとするとメソッドが肥大化していく。その各々の処理をStrategyクラス側に任せることで、Context側ではどのStrategyを使うか、だけを決めればよくなるので、処理の見通しが良くなる。

StrategyパターンのPlantUMLの記述

文頭のStrategyパターンのクラス図をPlantUMLで書いたときのソースです。

@startuml Strategy Method
abstract class Strategy{
  --
  # {abstract} Entity func()
}
class Strategy1 extends Strategy{
  --
  # Entity1 func()
}
class Strategy2 extends Strategy{
  --
  # Entity2 func()
}
class Context{
  - strategy : Strategy
  --
  # Entity call() 
}

Context o-r- Strategy : contain >
@enduml

参考サイトURL

PHPによるデザインパターン入門 – Strategy〜戦略を切り替える
デザインパターン ~Strategy~