Strategy
デザインパターンとは
デザインパターンとはオブジェクト思考開発における先人たちが作り上げてきた便利な設計図です。
Gang of Four通称Gofが1994年に出版した『オブジェクト指向における再利用のためのデザインパターン』の中で23個の設計図が紹介されています。
Note
デザインパターンのサンプルコードはSwift4でまとめます。
ストラテジーパターンとは?
ストラテジーパターンは分岐の中でロジックを持った処理を書いてしまっている際、外部クラスとして抽出することで処理の見通をよくするパターンです。
ロジックを変更する際もクラスになっていればメンテナンスがしやすくなります。
サンプルコード
サンプルコードではゲームの難易度を例に解説を行なっています。本来は何かしらのロジックが入ったりするのですが、Strategyパターンを理解する上では必要ないので省略しています。
メソッドに全て書いてしまう悪い例
今回はロジックを入れていませんがprint(“複雑な処理”)ここにロジックが書かれている想定です。
サンプルコードには3行しかないで問題なく理解することができまが、これが数十行もしくは100行を超えてしまった場合著しく可読性が落ちてしまします。
enum Type {
case EASY
case NORMAL
case HARD
}
func playType(mode: Type) {
switch mode {
case .EASY:
print("複雑な処理")
print("敵のレベルは10")
print("回復アイテムドロップ率上昇")
case.NORMAL:
print("複雑な処理")
print("敵のレベルは30")
print("回復アイテムドロップ率にはデフォルト")
case.HARD:
print("複雑な処理")
print("敵のレベルは50!")
print("回復アイテムドロップ率減少")
}
}
Strategyパターン
悪い例を改良してEASY, NORMAL, HARDのロジックを持つそれぞれのクラスを作成しています。
enum Type {
case EASY
case NORMAL
case HARD
}
protocol Strategy {
func playType()
}
class Easy: Strategy {
func playType() {
print("複雑な処理")
print("敵のレベルは10")
print("回復アイテムドロップ率上昇")
}
}
class Normal: Strategy {
func playType() {
print("複雑な処理")
print("敵のレベルは30")
print("回復アイテムドロップ率にはデフォルト")
}
}
class Hard: Strategy {
func playType() {
print("複雑な処理")
print("敵のレベルは50!")
print("回復アイテムドロップ率減少")
}
}
playTypeメソッド
storategyTypeメソッドの中を見ると、悪い例で上げていたロジックを含む条件文がStorategyパターンを適応してシンプルになっていることがわかります。
func playType(type: Type){
strategyType(mode: type).playType()
}
func strategyType(mode: Type) -> Strategy{
switch mode.self {
case .EASY: return Easy()
case .NORMAL: return Normal()
case .HARD: return Hard()
}
}
呼び出し
playType(type: .HARD)
出力されるログ
複雑な処理
敵のレベルは50!
回復アイテムドロップ率減少
コード一覧
import UIKit
protocol Strategy {
func playType()
}
class Easy: Strategy {
func playType() {
print("複雑な処理")
print("敵のレベルは10")
print("回復アイテムドロップ率上昇")
}
}
class Normal: Strategy {
func playType() {
print("複雑な処理")
print("敵のレベルは30")
print("回復アイテムドロップ率にはデフォルト")
}
}
class Hard: Strategy {
func playType() {
print("複雑な処理")
print("敵のレベルは50!")
print("回復アイテムドロップ率減少")
}
}
enum Type {
case EASY
case NORMAL
case HARD
}
func playType(type: Type){
strategyType(mode: type).playType()
}
func strategyType(mode: Type) -> Strategy{
switch mode.self {
case .EASY: return Easy()
case .NORMAL: return Normal()
case .HARD: return Hard()
}
}
playType(type: .HARD)