2017-04-09 11 views
2

私はまだOOPと依存関係注入について学んでいます。私は苦労していることがあります。クラス内に新しいオブジェクトを作成する

以下は、コンストラクタを介して注入された別のデータベースクラスを持ち、getAllメソッドを使用してデータベースからすべての記事を返す単純なクラスです。私はDIが好まれていることを理解し、それはユニットテストでテストするクラスが容易になりますよう最善の方法であると、それを切り離しなど

class Articles { 
    private $Database; 

    public function __construct(Database $database) { 
     $this->Database = $database; 
    } 
    public function getAll() { 
     return $this->Database->query("SELECT * FROM Articles"); 
    } 
} 

をしかし、どのような場合、私は、アレイ内のすべてのこれらの項目を反復処理し、インスタンス化したいです別のクラスの中の各アイテムの新しいクラス? (この場合、タスクキューに入れられる新しいタスクになります)。キュークラスを挿入して再利用できますが、複数のインスタンスをインスタンス化しているのでTaskクラスを挿入できません私は現在、それを悪く注入することなくクラスの中で直接インスタンス化しています。そうですね:

class Articles { 
    private $Database; 
    private $Queue; 

    public function __construct(Database $database, Queue $queue) { 
     $this->Database = $database; 
     $this->Queue = $queue; 
    } 
    public function init() { 
     $tasks = []; 
     $articles = $this->getAll(): 
     foreach ($articles as $article) { 
      $item = new Task($article); 
      $tasks[] = $item; 
     } 
     $queue = $this->Queue($tasks); 
    } 
    public function getAll() { 
     return $this->Database->query("SELECT * FROM Articles"); 
    } 
} 

どのようにして私が望むものを達成できますか?私はコントローラ内でクラスをインスタンス化することができますが、それは意図的に、クラスのinitメソッドですべてのロジックがグループ化されるように、iterable配列をコントローラに公開するロジックを構築することを意味します。

アイデア?とにかく

+0

ユニットテストは非常に簡単になります私はあなたが複数の「タスク」、または「URLを」含めることができる「リスト」クラス、またはコレクションまたは何でもあなたはそれを呼びたいを追加する必要があると思いますまたは何でも(異なるリスト/コレクション/グループ)。このようにして、リストを挿入することができます。また、各データモデルタイプの個々のインスタンスを入力することもできます。 –

答えて

0

Taskは単にデータを表現するために使用されている場合、それは変わらないし、それを注入する必要はありません。..

あなたの問題を解決するには、Builderデザインパターンを使用するビルダーを注入し、それを使用することですあなたのオブジェクトを構築する。

// Abstract class for the builder 
abstract class BaseTaskBuilder { 

abstract public function build(); 
} 

//Concrete class for builder 
class GreatTaskBuilder extends BaseTaskBuilder{ 
public function build() { 
// return a new instance of GreatTask 
} 
} 

// Abstract class for task 
abstract class BaseTask{} 

// Concrete class for task 
class GreatTask extends BaseTask{} 

あなたがしなければならないことは、コードのようにビルダーを注入することだけです。

+0

しかし、クラス内でモデルオブジェクトをインスタンス化する必要があるという問題はまだ解決していませんか? – user5331188

0

私は自分のモデルをきれいに保つことを好みます。

Articleは、本当に、その時点でQueueないDatabaseをinjecする罰金ですが、...

あなたはいつもCRUD機能update()retrive()delete()insertgetAll()getOne($id)などを持っているデータモデルであります実際にはモデルではありません。

モデルにタスクとキューを作成する代わりに、そのプロセスを処理し、そこに依存性注入を使用するサービスクラスを作成する必要があります。

これは

+0

ありがとうございます。このシナリオでは、サービスクラスがどのように表示されるかの例を提示できますか? – user5331188

関連する問題