サーチ…


前書き

このトピックでは、PHPで実装されたよく知られているデザインパターンの例を示します。

PHPでのメソッド連鎖

Method Chainingは、 Martin Fowlerの「 Domain Specific Languages 」の書籍で説明されている手法です。メソッドの連鎖は次のように要約されます。

複数の修飾子を1つの式で呼び出すことができるように、修飾子メソッドがホストオブジェクトを返すようにします

この非連鎖/通常のコードを考えてみましょう(前述の本からPHPに移植されています)

$hardDrive = new HardDrive;
$hardDrive->setCapacity(150);
$hardDrive->external();
$hardDrive->setSpeed(7200);

Method Chainingを使用すると、上記の文をよりコンパクトに書くことができます。

$hardDrive = (new HardDrive)
    ->setCapacity(150)
    ->external()
    ->setSpeed(7200);

これを機能させるために必要なことは、連鎖したいメソッドでreturn $thisreturn $thisことだけです:

class HardDrive {
    protected $isExternal = false;
    protected $capacity = 0;
    protected $speed = 0;

    public function external($isExternal = true) {
        $this->isExternal = $isExternal;        
        return $this; // returns the current class instance to allow method chaining
    }

    public function setCapacity($capacity) {
        $this->capacity = $capacity;        
        return $this; // returns the current class instance to allow method chaining
    }

    public function setSpeed($speed) {
        $this->speed = $speed;        
        return $this; // returns the current class instance to allow method chaining
    }
}

それをいつ使用するか

Method Chainingを利用する主な用途は、内部ドメイン固有言語を構築する場合です。 Method Chainingは Expression BuilderおよびFluent Interfacesの ビルディングブロックです。 しかし、それらと同義ではありません 。メソッド連鎖はそれらを可能にするだけです。ファウラーを引用する:

私はまた、共通の誤解に気付きました。多くの人々は流暢なインターフェースをメソッドチェインと同一視しているようです。確かにチェーンは流暢なインターフェイスで使用する一般的なテクニックですが、本当の流暢さはそれ以上のものです。

これで、ホストオブジェクトを書くのを避けるためだけにメソッドチェインを使用することは、多くの人がコードの匂いとみなすことになります 。それは、特に非連鎖APIと混合するときに、わかりにくいAPIを作成します。


その他の注意事項

コマンドクエリの分離

コマンドクエリ分離は、Bertrand Meyerによってもたらされた設計原則です。状態( コマンド )を変更するメソッドは何も返さないはずですが、何かを返すメソッド( クエリ )は状態を変更してはいけないと言います。これにより、システムについての理由を簡単に判断できます。 Method Chainingはこの原理に違反します。なぜなら我々は状態変えて何か返すからです。

ゲッターズ

メソッド連鎖を実装するクラスを使用する場合は、getterメソッド(つまり$this以外のものを返すメソッド)を呼び出すときに特に注意してください。 getterは$this以外の値を返さなければならないので、getterに追加のメソッドを連鎖すると、元のオブジェクトではなく、 取得された値で呼び出しが動作します。チェーンゲッターにはいくつかのユースケースがありますが、コードを読みにくくする可能性があります。

デメテルの法則とテストへの影響

上記の方法チェインは、Demeterの法則に違反していません。それはテストにも影響しません。これは、ホストインスタンスを返すためであり、共同作業者は返さないためです。 Fluent InterfacesExpression Buildersを使った単なるMethod Chainingを混乱させている人々に由来する一般的な誤解です。 Method Chainingがホストオブジェクト以外のオブジェクトを返すときのみ、Demeterの法則に違反し、テストでMock festsになります。



Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow