シンプルなデザインパターン:ストラテジーパターン
2018年3月1日2分で読める

シンプルなデザインパターン:ストラテジーパターン

この記事はAIによって翻訳されたため、不正確な場合があります。

免責聲明: このブログ記事の翻訳はAIによって生成されました。翻訳の正確性について保証はありません。重要な情報については、元の記事をご参照ください。

カバー写真は JESHOOTS.COM による Unsplash より

このシリーズについて...

GoFデザインパターンの学習は、私が開発者になってからの目標です。私にとって、デザインパターンの基本的な理解を持つことは、優秀な開発者になるための基盤の一つです。JavaScriptは純粋なオブジェクト指向プログラミング言語ではなく、ReactReduxなどの人気のあるフロントエンドフレームワークは、より関数型プログラミングのように動作しますが、学習することは非常に価値があると思います。賢い人々がソフトウェア開発の問題をどのように解決するかを理解することで、ソフトウェア設計の問題により多くのインスピレーションで対処し、より良いコードを書き、車輪の再発明を防ぐのに役立ちます。

GoFデザインパターンを学習するリソースはたくさんありますが、Web開発者向けに特化したものはそれほど多くなく、複雑なUML図や難しい専門用語を含むものもあります。関連する背景のないWeb開発者にとって、時には開始するのが困難な場合があります。パターンをより詳細に学習したい場合は、このサイトが良いと思います。

そこで、このシリーズでは、以下の方法ですべてをシンプルにしようと思います:

  1. 平易な言葉でパターンの理解を解釈する
  2. パターンの高レベル概念を抽出する
  3. JavaScriptでパターンを実装する簡単な例を使用する

このシリーズが、デザインパターンを学習したいWeb開発者がこれらのパターンをより良く理解するのに役立つことを願っています。

私は個人的により一般的だと思うパターンから始め、現時点で簡単な例を実装するには難しすぎると思われるパターンや、Web開発に関連していないと思われるパターンはスキップするかもしれません。

シリーズの最後に、デザインパターンがどのようにして私たちをより良いWeb開発者にするかについての私の観点の結論を述べます。


ストラテジーパターン

時間がない場合、この記事の一文バージョンは次のとおりです:

実装ではなく、インターフェースに対してプログラムする。


Wikipediaの定義は

コンピュータプログラミングにおいて、ストラテジーパターンポリシーパターンとも呼ばれる)は、実行時にアルゴリズムを選択することを可能にする行動型ソフトウェアデザインパターンです。

Johnは仕事に行かなければなりません。彼が仕事に行く方法はcurrentWeathercurrentTimeによって決まります。今のところ、彼の唯一の方法は歩くことです。

var john = new People()
john.walk()

数週間が経ちました...

Johnは自転車を買うのに十分なお金を持っており、今は別の選択肢があります。

再コーディングしましょう!

var john = new People()
if (currentWeather === 'sunny' && currentTime > 9) {
  john.bike()
} else {
  john.walk()
}

この例では、メソッドwalk()bike()は「仕事に行く」タスクのアルゴリズムの詳細です。このコードは理想的ではありません。アルゴリズムの詳細を変更するとき、クライアント側のコードも変更する必要があります。Johnが将来車を買った場合、またはJohnが雨の時に歩いて仕事に行く場合はどうでしょうか。クライアント側のコードはすぐに臭くなります。

一つの解決策は、walk()bike()メソッドを一段階高いgoToWork()に抽象化することです

var john = new People()
john.goToWork(currentWeather, currentTime)

OOPでのgoToWork()の実際の実装は、このシリーズの範囲を少し超えています。興味がある場合は、これをご覧ください。

簡単にするために、goToWork()が次のように動作すると想像できます:

class People {
  // ...クラス内のプロパティ
  goToWork(currentWeather, currentTime) {
    let strategy = null
    if (currentWeather === 'sunny' && currentTime > 9) {
      strategy = this._walk.bind(this)
    } else {
      strategy = this._bike.bind(this)
    }
    strategy()
  }
}

この場合、Johnがどのように仕事に行っても、クライアント側のコードには影響しません。クライアント側とアルゴリズムは両方とも合意された関数名(インターフェース)goToWork()に依存しています。move()のように関数名を一般的すぎないよう注意してください。

典型的な実世界の例は入力検証です。クライアント向けにisNumber()isEmpty()isValidLength()などの関数の束を書く代わりに、validate()関数を提供し、検証の詳細を処理させることができます。


結論

ストラテジーパターンは最も広く使用されるパターンの一つです。多くの場所で実装できるからです。アルゴリズムの詳細を抽象化することで結合レベルを下げます。この記事が役立つことを願っています。この記事の内容や私の理解に間違いがある場合は、お知らせください。ありがとうございます!

参考文献