Ankündigung

Einklappen
Keine Ankündigung bisher.

DI-Container Key

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • G.Schuster
    antwortet
    Zitat von notyyy Beitrag anzeigen
    wenn ich meinem system einen di container spendiere dann ja nicht ohne hintergrund. die interfaces für den container werden vom entwickler des systems geschrieben, damit ist davon auszugehen, dass das interface die methode implementiert. wenn nicht ist es schlichtweg ein fehler.
    Wer schreibt denn das System?
    Dann kannst du genauso gut davon ausgehen, dass bei einem simplen Namen einfach davon auszugehen ist, dass alles passend ist.

    Für mich klingt die ganze Diskussion nach absoluter Korinthen... und vollkommen überflüssig.
    Wenn du dich auf nichts verlassen willst, lass dich miniaturisieren und setzt dich selbst an die Bits, um sie zu schubsen.
    Alles mit unnötigen Interfaces zuzupflastern hilft weder der Performance, noch der Verständlichkeit geschweige denn der Wartbarkeit.
    K.I.S.S. for the win!

    Einen Kommentar schreiben:


  • Gast-Avatar
    Ein Gast antwortete
    Ich verstehe schon. Aber das Problem, das bleibt, ist, dass Du in einer großen Applikation einen Haufen Interfaces hast, die nur zur Identifikation dienen. Aber das ist halt Geschmacksfrage.


    EDIT: Es gibt einen eklatanten Nachteil: Jeder Service muss ein passendes Interface implementieren. Was machst Du bei Drittanbietern? Deren Klassen ableiten, damit die das Interface implementieren können?

    Einen Kommentar schreiben:


  • notyyy
    antwortet
    Zitat von xm22 Beitrag anzeigen
    Du kannst genauso wenig davon ausgehen, dass das Interface ilogger auch die Methode log implementiert.
    wenn ich meinem system einen di container spendiere dann ja nicht ohne hintergrund. die interfaces für den container werden vom entwickler des systems geschrieben, damit ist davon auszugehen, dass das interface die methode implementiert. wenn nicht ist es schlichtweg ein fehler.

    dadurch ist aber gewährleistet, dass jemand der meinen service ersetzt auch die nötige API für den service implementiert.

    wenn ich eine setter / getter injection habe und ein interface mit angebe habe ich identische vorteile, muss mir jedoch neben dem interface zusätzlich auch den schlüssel für den zugriff auf den service merken.

    Einen Kommentar schreiben:


  • Gast-Avatar
    Ein Gast antwortete
    ist nicht praktikabel weil du nicht sicher gehen kannst das der serive logger auch die funktion log implementiert.
    Schon klar, aber Du kannst genauso wenig davon ausgehen, dass das Interface ilogger auch die Methode log implementiert.. An irgendeiner Stelle musst Du Dich darauf verlassen, dass Du ein passendes Objekt bekommst.

    Einen Kommentar schreiben:


  • notyyy
    antwortet
    Zitat von xm22 Beitrag anzeigen
    EDIT: Ich verstehe jetzt nicht ganz, wo Du Typsicherheit vermutet hast: Bei den Parametern, die der aufgerufene Service bekommt oder ging es um den Service, der zurück gegeben wurde?
    wenn du via namen auf einen service zugreifst musst du

    1. seinen namen wissen
    2. seinen typ wissen

    $di->get('logger')->log('LOG!');

    ist nicht praktikabel weil du nicht sicher gehen kannst das der serive logger auch die funktion log implementiert. wenn du generell sagst, jeder service muss ein interface sein ist dies völlig legal:

    $di->get('ilogger')->log('LOG!');

    du bekommst einfach die aktuelle klasse welche auf das interface ilogger gemappt ist und kannst sichergehen, dass die log funktion existiert.

    Einen Kommentar schreiben:


  • Gast-Avatar
    Ein Gast antwortete
    Dass es sich um verschiedene Services handelt, gebe ich Dir recht, aber
    dann muss eine davon eine andere aufgabe erfüllen als die andere
    Was wäre denn, wenn per Zufallsprinzip eine von beiden ausgewählt wird (quasi Load-Balancing). Dann trotzdem noch zwei Interfaces?

    alles was man ohne vertrag blind austauscht ist einer meinung nach grob fahrlässig da es keinerlei gewährleistung dafür gibt
    Wie schon gesagt: Die Übergabe eines Interface-Namens ist doch nichts anderes als die Bezeichnung eines Services, den Du unter dieser Adressierung findest. Genau so wie bei dem anderen Ansatz. Du kannst Dich also genauso wenig auf den Typ der Rückgabe verlassen.

    Einen Kommentar schreiben:


  • notyyy
    antwortet
    Zitat von joshiausdemall Beitrag anzeigen
    Der Sinn eines DIC ist gerade die Austauschbarkeit der Komponenten und die Entkopplung selbiger. Wenn Du als Adresse jeweils den vollqualifizierten Namespace-Name verwendest - was hättest Du dann gewonnen?
    Nur weil 2 Services identische interfaces implementieren sind es noch lange nicht identische services. Solang die Aufgabe der Services identisch ist, nutzen sie identisches Interface. das könnte z.b. bei Datenbanktreibern der fall sein.

    wenn allerdings 2 datenbankverbindungen existieren, dann muss eine davon eine andere aufgabe erfüllen als die andere. im Klartext bedeutet das für mich wir haben unterschiedliche services. beiden services impementieren demnach ein eigenes interface.

    Sinn eines DIC ist ja nicht, dass man willkürlich irgendwelche objekte injizieren kann sondern, dass man ein system austauschbar hält. um ein system so aufzubauen sind Verträge von nöten, alles was man ohne vertrag blind austauscht ist einer meinung nach grob fahrlässig da es keinerlei gewährleistung dafür gibt, dass die klassen miteinander arbeiten können.

    Einen Kommentar schreiben:


  • joshiausdemall
    antwortet
    mir fällt grade auf, dass das großer unfung war. durch eine contructor oder einer setter injection ist ja wieder typensicherheit gewährleistet.
    Richtig.

    , sind sie nach meinem Verständnis unterschiedliche services und sollten unterschiedliche interfaces implementieren. für jeden service den man injizieren wollen möchte, müsste man selbstverständlich mind. ein interface hinterlegen.
    Ne, das ist ein falsches Verständnis. Alle Connections teilen das gleiche Interface, nur die Implementierung ist unterschiedlich. Sonst würd´s doch keinen Sinn machen, oder?

    Außerdem: Der Sinn eines DIC ist gerade die Austauschbarkeit der Komponenten und die Entkopplung selbiger. Wenn Du als Adresse jeweils den vollqualifizierten Namespace-Name verwendest - was hättest Du dann gewonnen?

    Einen Kommentar schreiben:


  • Gast-Avatar
    Ein Gast antwortete
    Ah, ich verstehe.. Stimmt, das sind zwei verschiedene Services. Aaaaaber, um beim Bsp. mit den Datenbanken zu bleiben. Angenommen, Dein Interface für 'db' sieht so aus:
    PHP-Code:
    interface DB {
        public function 
    setUsername();
        public function 
    setPassword();
        
    //...

    Da würdest Du jetzt für 'db2' ein weiteres, bis auf den Namen identisches Interface bauen?

    betroffene klassen müssen jedoch von dem service wissen, ansonsten können sie diesen nicht ansprechen.
    Logisch - Aber ansonsten müssten sie auch von dem Interface wissen. Das ist gehüpft wie gesprungen.

    wenn man jeden service gegen ein interface implementieren müsste wäre dieses problem quasi nicht mehr vorhanden.
    Kann ich nachvollziehen, aber ich finde trotzdem, da macht man sich unheimlich viel Arbeit und schafft enorm viel Redundanz. Und Wenn Du Dich schon bei der Varianten mit den Service-Bezeichnern nicht darauf verlassen kannst, dass Du einen korrekten Service zurück bekommst, dann kannst Du das mit den Interfaces auch nicht.


    EDIT: K.A., ob Du den Thread gelesen hast: http://www.php.de/software-design/81...container.html Das ist mein Ansatz, allerdings halt mit Bezeichnern statt Interfaces.


    EDIT: Ich verstehe jetzt nicht ganz, wo Du Typsicherheit vermutet hast: Bei den Parametern, die der aufgerufene Service bekommt oder ging es um den Service, der zurück gegeben wurde?

    Einen Kommentar schreiben:


  • notyyy
    antwortet
    mir fällt grade auf, dass das großer unfung war. durch eine contructor oder einer setter injection ist ja wieder typensicherheit gewährleistet.

    PHP-Code:
    /**
    * @inject document
    */
    public function getDocumentService(/xyz/document $document); 

    Einen Kommentar schreiben:


  • notyyy
    antwortet
    Zitat von xm22 Beitrag anzeigen
    Welche Grundproblematik?
    die aufgeführte problematik war, dass wenn man identische klassen mit unterschiedlichen konfigurationen hat, welche beide identisches interface besitzten, meine idee nicht aufgehen kann. Beispiel waren 2 datenbanken mit mit unterschiedlichen konfigurationen.

    ein di container kann jedoch unter einem schlüssel auch nur ein service mit einer konfiguration anbieten. demnach müsste man für die 2. datenbank einen 2. service definieren der identische klassen mit einer anderen konfiguration anbietet.

    betroffene klassen müssen jedoch von dem service wissen, ansonsten können sie diesen nicht ansprechen.

    demnach handelt es sich in meinen augen nicht um den selben service, sonderen es gibt 2 verschiedene services welche unterschiedliche aufgaben erfüllen und demnach auch ein unterschiedliches interface gerechtfertigt wäre.


    mich stört, dass man services willkürlich tauschen kann und man keinerlei möglichkeit hat wirklich typensicher ohne viel gecaste zu arbeiten. wenn man jeden service gegen ein interface implementieren müsste wäre dieses problem quasi nicht mehr vorhanden.

    Einen Kommentar schreiben:


  • Gast-Avatar
    Ein Gast antwortete
    omit die grundproblematik weiterhin bestehen würde.
    Welche Grundproblematik?

    Einen Kommentar schreiben:


  • notyyy
    antwortet
    Zitat von joshiausdemall Beitrag anzeigen
    Stell Dir bspw. vor, du verwendest zwei Datenbanken. Damit auch zwei DatabaseConnections => 2 unterschiedliche Konfigurationen, dasselbe Interface.
    das wäre ja völlig unproblematisch, wenn die datenbanken jedoch unterschiedliche aufgaben haben, sind sie nach meinem Verständnis unterschiedliche services und sollten unterschiedliche interfaces implementieren. für jeden service den man injizieren wollen möchte, müsste man selbstverständlich mind. ein interface hinterlegen.

    aber ich verstehe schon die problematik, auch sollte ein interface nichts über die belange und den kontext wissen in dem es verwendet wird. bei meiner lösung wäre dies ja der fall.

    indirekt besteht die problematik ja aber auch bei dem klassischen di container. $di->get('db') gibt ja im rahmen der di instanz immer identisches objekt mit identischer konfiguration zurück. wenn die klasse plötzlich mit einer anderen datenbank agieren muss, wird die klasse ja einen anderen schlüssel nutzen $di->('db2') omit die grundproblematik weiterhin bestehen würde.

    ich werde mich nochmal intensiv damit auseinandersetzen und mal schauen welche lösungen noch gangbar wären, insbesondere stört mich die nicht vorhandene typensicherheit.

    Zitat von joshiausdemall Beitrag anzeigen
    und ist hier beschrieben: http://bit.ly/5yMot
    vielen dank, schaue ich mir an, vielleicht erleuchtet mich das ja

    Einen Kommentar schreiben:


  • joshiausdemall
    antwortet
    Nö warum? Stell Dir bspw. vor, du verwendest zwei Datenbanken. Damit auch zwei DatabaseConnections => 2 unterschiedliche Konfigurationen, dasselbe Interface.

    Interface injection ist im Grunde 'ne coole Sache, aber "unter der Haube" müssen Services immer einen eindeutigen Identifizierer haben. Alles weitere ist i.d.R. "syntaktic Sugar" und wird auf den eigentlichen DI draufgepappt. So kann man Services "guessen" (indem man bspw. Signaturen analysiert), eine andere herangehensweise ist unter anderem das Mapping durch NamingConventions von Properties (so macht Grails das in seinen Controllern) => "myMailerService" oder so. Das "Problem" heißt generell "ServiceLocator vs. Injection" und ist hier beschrieben: http://bit.ly/5yMot

    Einen Kommentar schreiben:


  • Gast-Avatar
    Ein Gast antwortete
    dass diese dann unterschiedliche interfaces implementieren müssten
    Vielleicht irre ich mich, aber ich finde, nicht. Bsp.: Man hat einen File-Handler, der vielleicht mit einem Verzeichnis initialisiert werden muss. Gleiches Interface, Gleiche Klasse, aber unterschiedliche Parameter. So, wie Du das beschreibst, müsste ja für jeden Service ein eigenes Interface vorhanden sein.

    macht es sinn der klasse vorzuenthalten, dass dies unterschiedliche objekte sind?
    Die Klasse weiß doch davon gar nichts.

    Einen Kommentar schreiben:

Lädt...
X