目次
Gofの23パターンの1つで最も基本的なデザインパターンであるStrategyパターンについて説明します。
Strategyパターンとは?
Strategyを日本語に訳すると戦略の意味となり状況に応じてアルゴリズム(戦略)を切り替える設計パターンという意味になります。以下は実際に採用した実装例です。
- サーバのエンドポイントを本番サーバ・ステージングサーバ・モックサーバに切り替える
- データベースを仮想データベースと組込データベースで切り替える
- 物理ストレージのファイルパスをプラットフォーム別に切り替える
- View層のコードをユニットテストできるようにユーザーインターフェースをモックに切り替える
などなど、インターフェースを使った基本的なデザインパターンであるため、応用がかなり利ききます。
また、他のデザインパターンに組み込まれていたり、Strategyパターンと同じ構図のデザインパターンではあるけれど、用途が違うので呼称が違うこともあります。算数で例えるとStrategyパターンは足し算であり、掛け算や微分分数といった応用問題には足し算が使われていると言える関係です。
そのため、オブジェクト指向言語においてこのデザインパターンの理解は必須レベルだと思います。
実装例
例えばデータベースから取得したファイルパスにアクセスして物理ストレージから読み込んだファイルを一覧表示するViewを開発するとします。

画像と動画を表示する仕様を実装するにはImageViewとMovieViewのUIが必要なことが分かります。しかし、データベースには登録されているけど、物理ストレージのファイルが何かしらの理由で削除されて存在しないケースを想定してNullViewという壊れたファイルを示すUIも用意します。それに加えて、ユニットテストできるようにMockMediaViewというクラスも用意します。
そうなるとUML図は下記のようになります。

そして、上記のViewを一覧表示するMediaListViewというUIが必要で、データベースと物理ストレージにアクセスするMediaRepositoryクラスが必要であると考えると下記のUML図となります。

MediaRepositoryはデータベースと物理ストレージにアクセスして下記のBaseMediaModelの実装クラスを返します。
ImageMediaModel・・・画像ファイル
MoviewMediasModel・・・動画ファイル
NullMediaModel・・・・・ファイルがない等のなんらかのエラーがある場合

MediaListViewのAddListメソッドはMediaRepositoryからBaseMediaModelを受け取り、それをswitch文で分岐してメディアの一覧表示に追加するのでAddMediaメソッドは下記のようなコードになります。
private AddMedia(int id)
{
var model = _mediaRepository.GetById(id);
switch(model){
case ImageMediaModel image:
_list.Add(new ImageView(image));
break;
case Movie movie:
_list.Add(new MovieMediaView(image));
break;
case NullMediaModel noting:
_list.Add(new NullMediaView(noting));
break;
}
}
さいごに
近年ではMVVMパターンなど新しい設計が考案されていますが、Strategyパターンという枯れた設計を知らない人が結構います。新しい設計の習得も必要ですが、足し算の問題を関数電卓ライブラリを使って微分分数で解くような変な設計を作らないように、基本的なデザインパターンの理解を優先しましょう。