PHP デザイン パターン シリーズ -- 戦略パターン (戦略)

WBOY
リリース: 2016-06-20 12:40:32
オリジナル
1086 人が閲覧しました

1. パターン定義

ソフトウェア開発では、さまざまな環境や条件に応じて、さまざまなアルゴリズムや戦略が使用されます。この機能を完了するには、さまざまなアルゴリズムまたは戦略を選択してください。検索や並べ替えなど、一般的なメソッドはクラス内でハードコーディングされます。複数の検索アルゴリズムを提供する必要がある場合は、これらのアルゴリズムをクラスに記述し、各メソッドが特定のクラスに対応するようにすることができます。検索アルゴリズム; もちろん、これらの検索アルゴリズムを統一メソッドでカプセル化し、if...else... や case などの条件文を通じて選択することもできます。これら 2 つの実装方法をハード コーディングと呼びます。新しい検索アルゴリズムを追加する必要がある場合は、カプセル化されたアルゴリズム クラスのソース コードを変更して、検索アルゴリズムを変更する必要があります。また、クライアントの呼び出しコードも変更する必要があります。このアルゴリズム クラスは、多数の検索アルゴリズムをカプセル化します。このタイプのコードはより複雑になり、保守が困難になります。これらの戦略をクライアント側に組み込む場合、選択できるアルゴリズムが多数ある場合、クライアント プログラムが大きくなり、保守が困難になるため、このアプローチはさらに望ましくありません。

アルゴリズムをオブジェクトから分離して、アルゴリズムを使用するクライアントとは独立してアルゴリズムを変更できるようにするにはどうすればよいでしょうか?この目的のために、戦略パターンを紹介します。

ストラテジー モードは、アルゴリズム クラスター モードとも呼ばれ、さまざまなアルゴリズム ファミリを定義し、アルゴリズムを使用する顧客に関係なくアルゴリズムを変更できます。

一般的な使用シナリオには、日付または ID に基づくオブジェクト フィルタリングが含まれます。たとえば、単体テストでは、ファイル ストレージとメモリ ストレージを切り替えることができます。

2. UML クラス図

3. サンプルコード

ObjectCollection.php

<?phpnamespace DesignPatterns\Behavioral\Strategy;/** * ObjectCollection类 */class ObjectCollection{    /**     * @var array     */    private $elements;    /**     * @var ComparatorInterface     */    private $comparator;    /**     * @param array $elements     */    public function __construct(array $elements = array())    {        $this->elements = $elements;    }    /**     * @return array     */    public function sort()    {        if (!$this->comparator) {            throw new \LogicException("Comparator is not set");        }        $callback = array($this->comparator, 'compare');        uasort($this->elements, $callback);        return $this->elements;    }    /**     * @param ComparatorInterface $comparator     *     * @return void     */    public function setComparator(ComparatorInterface $comparator)    {        $this->comparator = $comparator;    }}
ログイン後にコピー

ComparatorInterface.php

<?phpnamespace DesignPatterns\Behavioral\Strategy;/** * ComparatorInterface类 */interface ComparatorInterface{    /**     * @param mixed $a     * @param mixed $b     *     * @return bool     */    public function compare($a, $b);}
ログイン後にコピー

DateComparator.php

<?phpnamespace DesignPatterns\Behavioral\Strategy;/** * DateComparator类 */class DateComparator implements ComparatorInterface{    /**     * {@inheritdoc}     */    public function compare($a, $b)    {        $aDate = new \DateTime($a['date']);        $bDate = new \DateTime($b['date']);        if ($aDate == $bDate) {            return 0;        } else {            return $aDate < $bDate ? -1 : 1;        }    }}
ログイン後にコピー

IdComparator.php

<?phpnamespace DesignPatterns\Behavioral\Strategy;/** * IdComparator类 */class IdComparator implements ComparatorInterface{    /**     * {@inheritdoc}     */    public function compare($a, $b)    {        if ($a['id'] == $b['id']) {            return 0;        } else {            return $a['id'] < $b['id'] ? -1 : 1;        }    }}
ログイン後にコピー

4. テストコード

Tests/StrategyTest.php

<?phpnamespace DesignPatterns\Behavioral\Strategy\Tests;use DesignPatterns\Behavioral\Strategy\DateComparator;use DesignPatterns\Behavioral\Strategy\IdComparator;use DesignPatterns\Behavioral\Strategy\ObjectCollection;use DesignPatterns\Behavioral\Strategy\Strategy;/** * 策略模式测试 */class StrategyTest extends \PHPUnit_Framework_TestCase{    public function getIdCollection()    {        return array(            array(                array(array('id' => 2), array('id' => 1), array('id' => 3)),                array('id' => 1)            ),            array(                array(array('id' => 3), array('id' => 2), array('id' => 1)),                array('id' => 1)            ),        );    }    public function getDateCollection()    {        return array(            array(                array(array('date' => '2014-03-03'), array('date' => '2015-03-02'), array('date' => '2013-03-01')),                array('date' => '2013-03-01')            ),            array(                array(array('date' => '2014-02-03'), array('date' => '2013-02-01'), array('date' => '2015-02-02')),                array('date' => '2013-02-01')            ),        );    }    /**     * @dataProvider getIdCollection     */    public function testIdComparator($collection, $expected)    {        $obj = new ObjectCollection($collection);        $obj->setComparator(new IdComparator());        $elements = $obj->sort();        $firstElement = array_shift($elements);        $this->assertEquals($expected, $firstElement);    }    /**     * @dataProvider getDateCollection     */    public function testDateComparator($collection, $expected)    {        $obj = new ObjectCollection($collection);        $obj->setComparator(new DateComparator());        $elements = $obj->sort();        $firstElement = array_shift($elements);        $this->assertEquals($expected, $firstElement);    }}
ログイン後にコピー

5. まとめ

戦略パターンは、主に一連のアルゴリズムを対象とし、各アルゴリズムを共通のインターフェースを持つ独立したクラスにカプセル化して、それらを置き換えることができます。お互い。戦略パターンにより、クライアントに影響を与えることなくアルゴリズムを変更できます。一般に、ストラテジー パターンは、アプリケーションが特定のサービスまたは機能を実装する必要があり、アプリケーションに複数の実装方法がある場合の使用に適しています。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート