2017-09-22 1 views
0

私のサンプルコードのどのバージョンが、オブジェクト指向の方が適切で正しいですか?サービスでクラスを渡すときとタイプヒントを使用するとき

1)

class ServiceA 
{ 
    private $serviceB; 

    public function __construct(ServiceB $serviceB) 
    { 
     $this->serviceB = $serviceB; 
    } 

    public function first() : int 
    { 
     return 1 + $this->serviceB->second(); 
    } 
} 

class ServiceB 
{ 
    public function second() : int 
    { 
     return 2; 
    } 
} 

2)

class ServiceA 
{ 
    private $serviceB; 

    public function __construct($serviceB) 
    { 
     $this->serviceB = $serviceB; 
    } 

    public function first() : int 
    { 
     return 1 + $this->serviceB->second(); 
    } 
} 

class ServiceB 
{ 
    public function second() : int 
    { 
     return 2; 
    } 
} 

クラスは汎用性と変更が容易でなければならない場合がタイプヒントであってはならないので、これは、タイプ・ヒンティングコンストラクタにすることなく、あります。

3)

class ServiceA 
{ 
    private $serviceB; 

    public function __construct() 
    { 
     $this->serviceB = new ServiceB(); 
    } 

    public function first() : int 
    { 
     return 1 + $this->serviceB->second(); 
    } 
} 

class ServiceB 
{ 
    public function second() : int 
    { 
     return 2; 
    } 
} 

私はいつも、このクラスでServiceBを使用したいので。しかし、それはデメテルの法律を破ることはありませんか?

4)

class ServiceA 
{ 
    private $serviceB; 

    public function first() : int 
    { 
     $this->serviceB = new ServiceB(); 

     return 1 + $this->serviceB->second(); 
    } 
} 

class ServiceB 
{ 
    public function second() : int 
    { 
     return 2; 
    } 
} 

これは私がそれをしたい場所私はそこServiceBを使用3.と同様です。

5)

class ServiceA 
{ 
    public function first() : int 
    { 
     $serviceB = new ServiceB(); 

     return 1 + $serviceB->second(); 
    } 
} 

class ServiceB 
{ 
    public function second() : int 
    { 
     return 2; 
    } 
} 

最も単純なバージョン。

すべての例では、ServiceAでは常にServiceBを使用する必要があることを意味します。 ServiceBをServiceCに変更したい場合は、ServiceAクラスの内容を変更する必要があります。この場合、例1を使用する必要がありますか?

私はこれらのクラスを1つの責任の原則を保つために分離しており、常に一緒に作業しなければなりません。さらに、ServiceBでは他の場所でも使用しています。

+0

なし公開されていないメソッドの公開スコープ –

+0

@LawrenceCherone彼はおそらくLaravelの[visual debt](https://laracasts.com/series/php-bits/episodes/1)フォロワーの1人です –

+0

私は編集しました私の質問。 – veguv

答えて

0

あなたのコードは、混乱や誤解を避けるために、何をしているのかを正確に伝える必要があります。だからバージョンは5でなければなりません)。それは、「Aを作成し、どこか別の場所に構成されたBのインスタンスで構成することができます」と読み取るため

  1. この例は良くありません。

  2. コンストラクタパラメータについて何も教えてくれないので、1)より悪いです。柔軟性が必要な場合は、インターフェイスを使用する必要があります。

  3. 「Aは常にBが必要であり、複数の場所で使用する可能性があります」と読みます。

  4. 悪いコードの例です。 BをAで怠惰に初期化したければ、あなたの意図をはっきりと伝えるファクトリメソッドに入れるべきです。

  5. 「メソッドの最初のニーズB」は、まさにあなたが望むものです。

Bの初期化に重い場合別の可能な解決策は、プロパティに遅延し、店舗、それを初期化することである。また、

/** 
* @var B 
*/ 
private $_b 

private function getB() : B 
{ 
    if (!$this->_b) { 
     $this->_b = new B(); 
    } 

    return $this->_b; 
} 

、常にBを必要とする場合は、ドメインからaggregatesを見ているかもしれません駆動設計。しかし、私たちはあなたのプロジェクトについてあまり知らないので、ここで良いことをアドバイスするのは難しいです。

私の一般的なアドバイスは、異なるオブジェクト間の抽象または関係が不明な場合に、最も簡単なコードを書くことです。あなたの質問で5)は、必要に応じて1)または3)に簡単にリファクタリングすることができます。だからこの時点で、そのような質問に時間を無駄にする必要はありません。時間とともに進化するものとしてあなたのコードを見てください。あなたが書くコードのそれぞれに最終的な解決策を提供する必要はありません。

関連する問題