0
3

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 5 years have passed since last update.

Swiftでデザインパターン【Strategy】

Last updated at Posted at 2020-09-04

元ネタ → ochococo/Design-Patterns-In-Swift

クラス図

image.png

図の引用元:Wikipedia: Strategy パターン

概要

The strategy pattern is used to create an interchangeable family of algorithms from which the required process is chosen at run-time.
Strategyパターンは、アルゴリズムが交換可能なファミリを作成しておき、それらの中から実行時に必要なプロセスが選択されるように利用する。
ファミリStrategy必要なプロセスの定義をしている。ファミリの構成員はConcreteStrategyA/B必要なプロセスアルゴリズムとして実装している。

サンプルコード

struct TestSubject {
    let pupilDiameter: Double
    let blushResponse: Double
    let isOrganic: Bool
}

// Strategy
protocol RealnessTesting: AnyObject {
    // AlgorithmInterface()
    func testRealness(_ testSubject: TestSubject) -> Bool
}

// ConcreteStrategyA
final class VoightKampffTest: RealnessTesting {
    // AlgorithmInterface()
    func testRealness(_ testSubject: TestSubject) -> Bool {
        return testSubject.pupilDiameter < 30.0 || testSubject.blushResponse == 0.0
    }
}

// ConcreteStrategyB
final class GeneticTest: RealnessTesting {
    // AlgorithmInterface()
    func testRealness(_ testSubject: TestSubject) -> Bool {
        return testSubject.isOrganic
    }
}

// Context
final class BladeRunner {
    // Containment
    private let strategy: RealnessTesting

    init(test: RealnessTesting) {
        self.strategy = test
    }

    // ContextInterface
    func testIfAndroid(_ testSubject: TestSubject) -> Bool {
        return !strategy.testRealness(testSubject)
    }
}


// usage //

let rachel = TestSubject(pupilDiameter: 30.2,
                         blushResponse: 0.3,
                         isOrganic: false)

// Deckard is using a traditional test
let deckard = BladeRunner(test: VoightKampffTest())
let isRachelAndroid = deckard.testIfAndroid(rachel)

// Gaff is using a very precise method
let gaff = BladeRunner(test: GeneticTest())
let isDeckardAndroid = gaff.testIfAndroid(rachel)

クラス図との対応

サンプルコード クラス図
RealnessTesting Strategy
testRealness AlgorithmInterface
サンプルコード クラス図
VoightKampffTest, GeneticTest ConcreteStrategy
testRealness AlgorithmInterface
サンプルコード クラス図
BladeRunner Context
strategy Containment(集約)
testIfAndroid ContextInterface

考察

Strategyパターンは、アルゴリズムが交換可能なファミリを作成しておき、それらの中から実行時に必要なプロセスが選択されるように利用する。
ファミリStrategy必要なプロセスを定義をしている。ファミリの構成員はConcreteStrategyA/B必要なプロセスの定義に準拠した具体的なアルゴリズムとして実装することで交換可能になっている(ポリモフィズム)。ContextはプロパティとしてStrategyのインスタンスstrategyを持ち(集約/aggregate、アップキャスト)、ContextInterfaceの実態はこのstrategyAlgorithmInterfaceである。Contextのインスタンス生成時(実行時)に、集約しているstrategyを決定することでContextInterfaceの実行内容(必要なプロセス)も決定される(ポリモフィズム)。

0
3
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
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?