php.de

Zurück   php.de > Webentwicklung > Software-Design

Software-Design Diskussionen auf Profi-Niveau: PHP Lösungen auf konzeptioneller Ebene

Antwort
 
LinkBack Themen-Optionen Thema bewerten
Alt 21.07.2011, 00:42  
Erfahrener Benutzer
 
Registriert seit: 12.05.2005
Beiträge: 1.038
PHP-Kenntnisse:
Fortgeschritten
notyyy befindet sich auf einem aufstrebenden Ast
Standard DI - Lazy

PHP unterstützt ja keinerlei Möglichkeit Variablen Lazy nachzuladen. Insbesondere bei vielen Abhänigkeiten im DiC kann dies problematisch sein, da alle Services von denen ein Service abhängig ist, vorher initialisiert werden müssen. Eine Möglichkeit dieses zu umgehen wäre:

PHP-Code:
class service implements iService {

  
/**
     * @var \de\iMailer
     * @inject
     * @lazy
     */
    
private $mailService;

    function 
doStomething() {
        
$this->mailService()->sendMail();
    }


in diesem Fall würde man von dem DiC anstatt des Services eine anonyme Funktion bekommen welche beim Aufruf die korrekte Instanz zurückgibt. Dies hat jedoch den gewaltigen Nachteil, dass die @var Annotation nur noch bedingt stimmt, die CodeCompletion funktioniert nicht mehr und womöglich sind einige Entwickler schnell verwirrt.


Vorteile:
+ Lazy

Nachteile
- "falsche" @var Annotation
- Verwirrung
- keine CodeCompletion

was sagt ihr zu einer solchen Implementierung?
notyyy ist offline   Mit Zitat antworten
Sponsor Mitteilung
PHP Code Flüsterer

Registriert seit: 21.08.2005
Beiträge: 4682
PHP-Kenntnisse:
Fortgeschritten

Alt 21.07.2011, 07:26  
fab
Erfahrener Benutzer
 
Benutzerbild von fab
 
Registriert seit: 28.07.2010
Beiträge: 2.308
PHP-Kenntnisse:
Fortgeschritten
fab ist ein Lichtblickfab ist ein Lichtblickfab ist ein Lichtblickfab ist ein Lichtblickfab ist ein Lichtblick
Standard

Ich sehe ehrlich gesagt gar nicht, warum es ein Problem sein sollte dass die Abhängigkeiten im Voraus initialisiert werden. Wenn eine Klasse von vielen Services abhängt und davon evtl. nur einen Teil braucht, würde ich mir erstmal überlegen ob sie nicht zu viele Aufgaben übernimmt und in mehrere Klassen gesplittet werden könnte.

Wenn du aber diesen Weg gehen willst, was spricht dagegen, das über getter zu machen (ggf. auch magische)? Du musst ohnehin einen Umweg gehen, denn $this->mailService() wird nicht funktionieren (versucht, die Methode mailService aufzurufen und nicht das Attribut als Closure!)

Hier mal ein erster Versuch mit magischem Getter (@method sorgt für korrekte Code Completion)

PHP-Code:
/**
 * @method \de\iMailer getMailService()
 */
class service implements iService {

  
/**
     * @var Closure
     * @inject
     * @lazy
     */
    
private $_getMailService;

    public function 
__call($method$args)
    {
        if (
substr($method(0,3) === 'get')
        {
            return 
call_user_func_array($this->{'_' $method}, $args);
        }
        
// Exception
    
}

    function 
doSomething() {
        
$this->getMailService()->sendMail();
    }


fab ist offline   Mit Zitat antworten
Alt 21.07.2011, 09:07  
Erfahrener Benutzer
 
Registriert seit: 02.09.2009
Beiträge: 1.020
PHP-Kenntnisse:
Fortgeschritten
mquadrat befindet sich auf einem aufstrebenden Ast
Standard

Ich würde mich fab anschließen. Wenn bei jedem Aufruf einer Klasse immer nur ein kleiner Teil der injecteten Services wirklich benötigt wird, dann wird wahrscheinlich SRP verletzt.
__________________
Wir suchen PHP Entwickler (Vollzeit) im Raum Darmstadt / Rhein-Main. Infos via E-Mail mueller@new-frontiers.de
mquadrat ist offline   Mit Zitat antworten
Alt 22.07.2011, 11:05  
Benutzer
 
Registriert seit: 16.07.2010
Beiträge: 80
PHP-Kenntnisse:
Fortgeschritten
SinnlosS befindet sich auf einem aufstrebenden Ast
Standard

Wie wärs die Services als Closures bereitzustellen, so dass sie erst initialisiert werden wenn sie auch tatsächlich angefordert werden.
Beispiel:
PHP-Code:

class arbitEnvironmentDIC extends arbitDependencyInjectionContainer {
    public function 
initialize() {
        
$this->cache = function($dic) {
            return new 
arbitFilesystemCache($dic->request->controller);
        }
    }

Das Beispiel ist geklaut aus Folie 21: http://qafoo.com/talks/11_02_phpuk_a...o_patterns.pdf
Da geht es genau um die von dir angesprochene Problematik.
Ein Video dazu gibts auch: http://ontwik.com/php/advanced-oo-patterns-in-php/
Und die komplette Klasse arbitDependencyInjectionContainer:
http://tracker.arbitracker.org/arbit..._container.php

Geändert von SinnlosS (22.07.2011 um 15:58 Uhr). Grund: Verlinkung zum SourceCode vom arbitDIC eingefügt
SinnlosS ist offline   Mit Zitat antworten
Alt 22.07.2011, 23:50  
Erfahrener Benutzer
 
Registriert seit: 12.05.2005
Beiträge: 1.038
PHP-Kenntnisse:
Fortgeschritten
notyyy befindet sich auf einem aufstrebenden Ast
Standard

Zitat:
Zitat von SinnlosS Beitrag anzeigen
Wie wärs die Services als Closures bereitzustellen
hab ich dich in meinem beispiel gemacht?

PHP-Code:
$this->mailService() 
...
notyyy ist offline   Mit Zitat antworten
Antwort


Themen-Optionen
Thema bewerten
Thema bewerten:

Forumregeln
Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are an
Gehe zu

Ähnliche Themen
Thema Autor Forum Antworten Letzter Beitrag
DB-Modell in OOP richtig aufbauen Squall PHP Tipps 2010 25 05.05.2010 19:36
[Erledigt] lazy by __call() vs. variable Interface-Auslegung nikosch Software-Design 22 09.05.2009 21:41
[Erledigt] PHP5: "Private Lazy Initialization" mit __get() mo PHP-Fortgeschrittene 10 16.10.2005 16:57

Besucher kamen über folgende Suchanfragen bei Google auf diese Seite
arbitdependencyinjectioncontainer

Alle Zeitangaben in WEZ +2. Es ist jetzt 01:37 Uhr.




Powered by vBulletin® Version 3.7.2 (Deutsch)
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.2.0
Aprilia-Forum, Aquaristik-Forum, Liebeskummer-Forum, Zierfisch-Forum, Geizkragen-Forum