2017-04-09 9 views
2

Ich lerne immer noch über OOP und Dependency-Injektion und es gibt etwas, mit dem ich kämpfe.Erstellen eines neuen Objekts innerhalb der Klasse

Unten ist eine einfache Klasse mit einer separaten Datenbankklasse, die über den Konstruktor eingefügt wird, und die getAll-Methode verwendet, um alle Artikel aus der Datenbank zurückzugeben. Ich verstehe, dass DI bevorzugt und ist beste Praxis, wie es die Klasse einfach macht, mit Unit-Tests zu prüfen und zu entkoppeln es usw.

class Articles { 
    private $Database; 

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

Aber was, wenn ich will diese Elemente alle in dem Array iterieren und instanziiert einer neue Klasse für jedes Element in einer anderen Klasse? (Dies wäre in diesem Fall eine neue Aufgabe, die dann in die Aufgabenwarteschlange gestellt würde.) Ich kann die Warteschlangenklasse einfügen und diese wiederverwenden, aber ich kann die Task-Klasse nicht einspeisen, da ich mehrere Instanzen davon instanziiere Ich instanziiere es momentan direkt in der Klasse, ohne es zu injizieren, was schlecht ist. Gefällt mir so:

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"); 
    } 
} 

Also wie kann ich erreichen, was ich begehre? Ich könnte die Klassen innerhalb eines Controllers instantiieren, aber das bedeutet, absichtlich Logik zu erstellen, um das iterierbare Array dem Controller zugänglich zu machen, wenn ich möchte, dass es in der init-Methode der Klasse ausgeführt wird, so dass die gesamte Logik gruppiert ist.

Irgendwelche Ideen?

+0

Ich glaube, Sie müssen hinzufügen, um eine „Liste“ Klasse, oder eine Sammlung oder was auch immer Sie es nennen wollen machen, die mehr „Aufgaben“ enthalten können, oder „URLs“ oder was auch immer (verschiedene Listen/Sammlungen/Gruppen). Auf diese Weise kann die Liste eingefügt werden und Sie können sie mit einzelnen Instanzen jedes Datenmodelltyps füllen, während Sie fortfahren. –

Antwort

0

Wenn Task wird nur verwendet, um Daten zu repräsentieren, dann wird es nicht ändern und keine Notwendigkeit, es zu injizieren ..

Auf jeden Fall eine Lösung für Ihr Problem ist das Builder Design-Muster zu verwenden, den Generator zu injizieren und es zu verwenden, um dein Objekt zu bauen.

// 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{} 

Also, alles, was Sie tun müssen, ist den Baumeister zu injizieren, wie Sie in Ihrem Code zu tun.

+0

Aber bleibt das Problem nicht, dass ich das Modellobjekt in einer Klasse instanziieren müsste? – user5331188

0

Ich bevorzuge es, mein Modell sauber zu halten.

Article ist ein Datenmodell, in dem Sie Ihre üblichen CRUD Funktionen update() haben, retrive(), delete(), insert, getAll(), getOne($id) etc ...

Es ist in Ordnung Database INJEC, aber nicht wirklich die Queue an diesem Punkt Es ist nicht wirklich ein Modell.

Anstatt Aufgaben und Warteschlangen in Ihrem Modell zu erstellen, sollten Sie eine Serviceklasse erstellen, die sich um diesen Prozess kümmert und dort auch die Abhängigkeitsinjektion verwendet.

Dies wird Unit-Test viel einfacher

+0

Danke, könnten Sie ein Beispiel dafür geben, wie die Serviceklasse in diesem Szenario aussehen könnte? – user5331188

Verwandte Themen