Antworten auf deine Fragen:
Neues Thema erstellen

Was spricht für Dependency Injection?

Hallo,

ich bin gerade dabei ein neues Projekt in die Wege zu leiten und überlege bei manchen Klassen, ob Singleton oder Dependency Injection besser geeignet ist.

Ein kleines Beispiel bei dem ich z.B. momentan auf dem Standpunkt stehe, dass Singleton am einfachsten und geeignetesten ist: Bei einer Applikation gibt es eine Configuration class die alle Settings lädt. Die Settings sind natürlich für alle Klassen interessant, die auf die Konfiguration Zugriff benötigen. Für mich ein klarer Fall für Singleton, denn die Konfiguration ändert sich während der Laufzeit ja nicht. Ein anderen Beispiel wäre eine Request class die Seitenrequests performt. Auch die würde ich nach dem Singleton-Pattern entwerfen, denn wer braucht schon zwei Instanzen von einem Request?!

Doch nun habe ich viel Kritik am Singleton mitbekommen und zum Teil von Arbeitgebern die Info bekommen, dass wer den Singleton verherrlicht, keine Anstellung findet. Allerdings ist die Kritik am Singleton solange die Klasse nicht vererbt werden muss und wirklich nur eine Instanz benötigt, nicht auf meinen Anwendungsfall gezielt. Deshalb frage ich mich ob meine Vorgehensweise richtig ist, oder ob ich doch Dependency Injection verwenden soll. Es ist aus meiner Sichtweise einfach umständlicher, denn ich müsste fast jeder Klasse die Configuration übergeben.

Wie sieht das aus, hat jemand Erfahrung mit meinem Anwendungsfall? Ich denke ich stehe da nicht alleine da, das ist das 1x1 für jedes Projekt. An welchen Stellen von Projekten sollte ich auf Dependency Injection zurückgreifen und an welchen nicht?
 

dcmagie

Auf der Suche

Ich denke für deine eigenen persönlichen Projekte kannst du doch das so Programmieren wie du das für richtig hältst.
Ansonsten musst du so Programmieren wie der Arbeitgeber es vorschreibt ,wenn das der Stiel der Firma ist. Da ist halt der Arbeitgeber der ,der die Richtung vorschreibt , es sei denn du kannst ihn vom Gegenteil überzeugen. Was aber schwierig sein könnte.
 
Ich meinte das jetzt garnicht so auf einen Arbeitgeber bezogen. Bleiben wir beim Beispiel: Mein persönliches Projekt an dem aber ggf. auch andere programmieren könnten. Die Fragen bleiben gleich.
 

tr4ze

Mod | Forum

Teammitglied
PSD Beta Team
Du versuchst hier Äpfel mit Birnen zu vergleichen. Singleton ist ein Erzeugungsmuster, DI gehört dagegen zu den sonstigen Mustern. Wobei es streng genommen gar kein Muster ist, sondern vielmehr eines der SOLID Prinzipien um Abhängikeiten von Klassen zu verringern(bzw. zu reglementieren).

Du kannst also ein Erzeugungsmuster nur mit einem anderen Erzeugungsmuster vergleichen, z.B.: singelton vs prototype.

In der Realität werden Singleton und DI oft mittels constructor injection kombiniert, indem der getInstance methode eine oder mehrere Resourcen mitgegeben wird.

Als Beispiel mal meine PDO Layer Klasse, welche ich zum schnellen Prototyping benutze.
Hier habe ich beide Muster kombiniert.
Das Singleton wurde etwas erweitert um zu Laufzeit auf verschiedene Datenbanken zu verbinden.

PHP:
<?php
/**
* PDO Database Layer Class
* extended Singelton Pattern
*
* @author tr4ze
* @Version 1.0
*
*/

class db
{
   
    private $host = null;

    private $user = null;

    private $pass = null;

    private $dbname = null;

    private $dbh;

    private $error;

    private $stmt;

    protected $db = null;

    private static $instances = Array();

    protected function __construct($host,$user,$pass,$dbname){
    
        // Set Propertys
        $this->host = $host;
        $this->user = $user;
        $this->pass = $pass;
        $this->dbname =$dbname;
        // Set DSN
        $dsn = 'mysql:host=' . $this->host . ';dbname=' . $this->dbname;
        // Set options
        $options = array(
            PDO::ATTR_PERSISTENT    => TRUE,
            PDO::ATTR_ERRMODE       => PDO::ERRMODE_EXCEPTION
        );
        // Create a new PDO instanace
        try{
            $this->dbh = new PDO($dsn, $this->user, $this->pass, $options);
        }
        // Catch any errors
        catch(PDOException $e){
            $this->error = $e->getMessage();
            echo $this->error;
        }
    }

    public static function getInstance($db,$host,$user,$pass,$dbname) {
        // Check for multiply instances
        if (!isset(self::$instances[$db])) {
        
            self::$instances[$db] = new db($host,$user,$pass,$dbname);
        }
        return self::$instances[$db];
    }
    public function query($query){
        $this->stmt = $this->dbh->prepare($query);
    }

    //  Param is the placeholder value that we will be using in our SQL statement, example :name.
    //
    //  Value is the actual value that we want to bind to the placeholder, example “John Smith”.
    //
    //  Type is the datatype of the parameter, example string.
        
    public function bind($param, $value, $type = null){
        if (is_null($type)) {
            switch (true) {
                case is_int($value):
                    $type = PDO::pARAM_INT;
                    break;
                case is_bool($value):
                    $type = PDO::pARAM_BOOL;
                    break;
                case is_null($value):
                    $type = PDO::pARAM_NULL;
                    break;
                default:
                    $type = PDO::pARAM_STR;
            }
        }
        $this->stmt->bindValue($param, $value, $type);
    }

    public function execute(){
        return $this->stmt->execute();
    }

    public function resultset(){
        $this->execute();
        return $this->stmt->fetchAll(PDO::FETCH_ASSOC);
    }

    public function single(){
        $this->execute();
        return $this->stmt->fetch(PDO::FETCH_ASSOC);
    }

    public function rowCount(){
        return $this->stmt->rowCount();
    }

    public function lastInsertId(){
        return $this->dbh->lastInsertId();
    }

    public function beginTransaction(){
        return $this->dbh->beginTransaction();
    }

    public function endTransaction(){
        return $this->dbh->commit();
    }

    public function cancelTransaction(){
        return $this->dbh->rollBack();
    }

    public function debugDumpParams(){
        return $this->stmt->debugDumpParams();
    }
    public function __destruct() {
    
    }
    private function __clone() {}
 
}

?>

Das funktioniert soweit ganz gut.... man hat einen Globalen Zugriffspunkt.
Allerdings ist genau das auch das Problem !!!
Kommen nun weitere Klassen ins Spiel die die Datenbank benötigen enstehen versteckte Abhängigkeiten.
PHP:
class article {

protected $db;

protected $articles = Array()

public function __construct (db $db) {
    
    $this->db = $db ;
    // der Rest des Constructors
    }
   // Alle weiteren Methoden
}

Ein Entwickler der die article() Klasse benutzen möchte sieht zwar das er ein Objekt vom Typ db benötigt, wo er dieses herbekommt bzw. wie er eines instanziert erschließt sich ihm aber nicht.
Schlimmer wird es wenn die Klasse db() selber Abhängikeiten hat, z.B.: von einer Klasse Config() welche wiederum von einer Klasse cms() abhängt und beide ebenfalls als SIngleton implementiert sind.
Das wird schnell unübersichtlich und du verstößt gegen mehrere Prinzipien objektorientierter Programmierung.

Besser ist es z.B das Singleton in Verbindung mit einer Factory zu nutzen, welche alle benötigten Klassen entweder zur Laufzeit instanziert oder in einem Repository bzw. einer Registry vorhält.

Ausserdem ist es möglich Abhängikeiten mit einem DI-Container zu verwalten, hier wären Frameworks wie Stubbles, Symfony oder Zend2 geeignete Kandidaten.

Du solltest dich aber grundsätzlich noch einmal mit OOP auseinandersetzen, ich kann z.B.: dieses Buch empfehlen
 
Bilder bitte hier hochladen und danach über das Bild-Icon (Direktlink vorher kopieren) platzieren.
Antworten auf deine Fragen:
Neues Thema erstellen

Willkommen auf PSD-Tutorials.de

In unseren Foren vernetzt du dich mit anderen Personen, um dich rund um die Themen Fotografie, Grafik, Gestaltung, Bildbearbeitung und 3D auszutauschen. Außerdem schalten wir für dich regelmäßig kostenlose Inhalte frei. Liebe Grüße senden dir die PSD-Gründer Stefan und Matthias Petri aus Waren an der Müritz. Hier erfährst du mehr über uns.

Stefan und Matthias Petri von PSD-Tutorials.de

Nächster neuer Gratisinhalt

03
Stunden
:
:
25
Minuten
:
:
19
Sekunden

Flatrate für Tutorials, Assets, Vorlagen

Zurzeit aktive Besucher

Keine Mitglieder online.

Statistik des Forums

Themen
118.565
Beiträge
1.538.067
Mitglieder
67.488
Neuestes Mitglied
Andrew56524
Oben