5

デメテルの法則によれば、返されたオブジェクトのメソッドを呼び出すことはできますか?

例えば

<?php
class O
{
    public function m($http)
    {
        $response = $http->get('http://www.google.com');
        return $response->getBody(); // violation?
    }
}
?>

$ http-> get()はオブジェクトを返します。これは、M内で作成/インスタンス化されたオブジェクトとしてカウントされますか?(LoDによると)メソッドを呼び出せない場合、この状況にどのように対処しますか?

4

3 に答える 3

6

これは、デメテルの法則に違反するものではありませ

より正式には、関数のデメテルの法則では、オブジェクトOのメソッドMは、次の種類のオブジェクトのメソッドのみを呼び出すことができる必要があります。

  • O自体
  • Mのパラメータ
  • M内で作成/インスタンス化されたオブジェクト
  • Oの直接コンポーネントオブジェクト
  • Mのスコープ内のOからアクセス可能なグローバル変数

$ responseはM内で作成されるオブジェクトであるため、違反することなくそのオブジェクトに対してメソッドを呼び出すことができます。ただし、以下を超えるプロパティにアクセスすることは違反となりますgetBody()

$length = $response->getBody()->length;

法則は「ワンドット」ルールであると言うことで簡略化できると言うことができます。つまり、1つのプロパティまたはメソッドに深くアクセスできます。

于 2010-06-09T14:10:44.197 に答える
6

一方では、$responseメソッド内で作成されたmように見えるため、答えはイエスのように見えます。

一方、$httpが に渡されたため、 によって返され、現在 によって表されているmオブジェクトは、に入る前に作成された のメンバーである可能性があります。$http->get()$response$httpm

法律の「唯一のドット」(または、この場合は矢印)の解釈を考慮して、関数の本体をreturn $http->get('http://www.google.com')->getBody();違反である可能性があることを示唆するように書き換えます。中間メンバーをローカル変数として保存することは、1 ドットの原則を回避するための危険な方法のように思えます。

決定的な答えは出せません。ある程度、$http->get()既存のメンバーではなく、新しく作成されたオブジェクトを提供することをどれだけ信頼できるかにかかっていると思います。

于 2010-06-09T14:24:55.353 に答える
1

これを解決する 1 つの可能性は、m() 内でオブジェクトを作成し、http->get() に情報を入力させることです。

class O
{
    public function m($http)
    {
        $response = new HttpResponse();
        $http->get('http://www.google.com', & $response);
        return $response->getBody(); // no violation, since we made $response ourselves.
    }
}
于 2010-06-09T17:43:13.487 に答える