[iOS 8] Swiftでデザインパターン No.6 Strategy
Strategy
Strategy とは
英単語 Strategy には以下のような意味があります。
- 戦略
Strategy パターンは、アルゴリズムを実行時に選択することができるパターンです。
クラス図
ポイント
- ConcreteStrategyA, ConcreteStrategyB で、それぞれ具体的な戦略を実装する
サンプルコード
Context
class Context { private let strategy: Strategy init(strategy: Strategy) { self.strategy = strategy } func executeStrategy(#num1: Int, num2: Int) -> Int { return strategy.execute(num1: num1, num2: num2) } }
Context は、イニシャライザで Strategy プロトコルを採用しているオブジェクトを受け取り、メンバ変数に保持します。 「#」については後述します。
Strategy
protocol Strategy { func execute(#num1: Int, num2: Int) -> Int }
Strategy はインターフェースなので、プロトコルとして記述します。
Add
class Add: Strategy { func execute(#num1: Int, num2: Int) -> Int { return num1 + num2 } }
Add クラスは ConcreteStrategyA に相当します。 Strategy プロトコルを採用する、足し算を実装する戦略クラスです。
Subtract
class Subtract: Strategy { func execute(#num1: Int, num2: Int) -> Int { return num1 - num2 } }
Subtract クラスは ConcreteStrategyB に相当します。 Strategy プロトコルを採用する、引き算を実装する戦略クラスです。
実行
var context: Context context = Context(strategy: Add()) let addResult = context.executeStrategy(num1: 2, num2: 4) println("Add result = (addResult)") context = Context(strategy: Subtract()) let subtractResult = context.executeStrategy(num1: 2, num2: 4) println("Subtract result = (subtractResult)")
実行結果
Add result = 6 Subtract result = -2
Strategy パターンを利用することで、利用するクライアントからは独立して、アルゴリズムを変更することができるようになります。
謎の文字「#」
「#」は Shorthand External Parameter Names というものを表現するシンボルです。
External Parameter Names
日本語で表すと「外部引数名」でしょうか。
let addResult = context.executeStrategy(num1: 2, num2: 4)
上記の例で言えば、num1 や num2 の部分が、外部引数名に該当します。 Swift ではメソッドの引数名を外部用と内部用で別々に持つことが可能です。
例
func test(a: Int, b: Int) {}
上記のようなメソッドが存在する場合、利用する側は通常以下のように記述しなければなりません。
test(2, b: 4)
これだと第一引数の名前が見えず、理解しづらいことがあります。 そんな時は以下のように書くことで引数名を表示させることができます。
// メソッド定義 func test(a a: Int, b: Int) {} // 利用する側 test(a: 2, b: 4)
最初の「a」が外部引数名、次の「a」が内部引数名となります。 また、外部引数名と内部引数名が同じ場合は更に短く以下のように書くことができます。
func test(#a: Int, b: Int) {}
この「#」が、Shorthand External Parameter Names と呼ばれるものの正体です。
まとめ
- Swift では外部引数名と内部引数名を別々に定義することができる
- 「#」は Shorthand External Parameter Names を表現するシンボル
- イニシャライザでは自動で外部引数名が設定される