Bu yapıcı enjeksiyon aklı başında bir uygulama mı?

3 Cevap php

my question on service locators yerine yapıcı enjeksiyon kullanmaya karar verdik den sonra. Aşağıdaki kodu göz önünde bulundurun:

<?php

    interface IAppServiceRegistry {
        public function getDb();
        public function getLogger();
    }

    interface IFooServiceRegistry extends IAppServiceRegistry {
        public function getFooBarBazModel();
    }

    class AppServiceRegistry
        implements IAppServiceRegistry, IFooServiceRegistry
    {
        private $logger;
        private $db;
        private $fooBarBazModel;

        public function getDb() {
            // return db (instantiate if first call)
        }

        public function getLogger() {
            // return logger (instantiate if first call)
        }

        public function getFooBarBazModel() {
            if (!isset($this->fooBarBazModel)) {
                $this->fooBarBazModel = new FooBarBazModel( $this->getDb() );
            }
            return $this->fooBarBazModel;
        }
    }

    // Example client classes:

    /**
     * Depends on db, logger and foomodel.
     */
    class Foo {
        private $db;
        private $logger;
        private $fooModel;

        public function __construct(IFooServiceRegistry $services) {
            $this->db = $services->getDb();
            $this->logger = $services->getLogger();
            $this->fooModel = $services->getFooModel();
        }
    }

    /**
     * Depends on only db and logger.
     */
    class BarBaz {
        private $db;
        private $logger;

        public function __construct(IAppServiceRegistry $services) {
            $this->db = $services->getDb();
            $this->logger = $services->getLogger();
        }
    }

Sonra mantıklı uygun yerde ayrılmış arayüzler yaratmak, gelişmiş uygulama olarak kayıt defterine yeni hizmet fabrika yöntemler eklersiniz.

Bu yaklaşım, aklı başında mı?

3 Cevap

Ben normalde php okumaz da, ben bunu çoğu anlıyorum. Teknik olarak gayet iyi görünüyor, ama sonra yazmak

Uygulama gelişti olarak ben kayıt defterine yeni hizmet Fabrika yöntemleri eklersiniz

Yani şimdi özel bir Hizmet Bulucu çünkü yerine genel amaçlı Hizmet Locator gevşek bağlanması fikrini zarar eğilimindedir.

Her sınıfa böyle bir serivce kayıt enjekte kez bir sınıf kayıt defterine erişimi olan, başlangıçta tasarlanmış daha başka bağımlılık istemek çok kolaydır çünkü Single Responsibility Principle (SRP) karşı çalışır, ve ile sona erecek a God Object.

Bu onları doğrudan gerek sınıflara gerekli bağımlılıkları enjekte etmek daha iyi olurdu. Barbaz sınıf yalnızca bir db ve logger bir parametre almalıdır iken Böylece, Foo sınıfının yapıcısı, bir db, bir logger ve bir fooModel almalıdır.

Sonraki soru olabilir: ben işi gerçekleştirmek için farklı bağımlılıkları çok ihtiyacınız varsa? Bu parametreleri birçok ile gerçekten çirkin bir kurucu gerektirir, ve bu diğer tanınmış OO uygulamalara karşı gider.

Eğer bağımlılıkları çok ihtiyacımız doğruysa, ancak, muhtemelen SRP ihlal ve ince daneli nesneler içine tasarım bölmek denemelisiniz :)

Bu uygulama hemen hemen önce bize gösterdi hizmet yerleştirici olarak aynıdır.

Sormak için iyi bir soru sizin nesnelerin sınıfa bakarak üzerine, size nesneler hakkında her şeyi kendi işi halletmek gerekiyor biliyor olup olmadığıdır. Sizin durumda hala bilmiyorum.

Foo db, logger ve modelini gerekiyorsa, kurucusuna bu sorarak bu açık olun.

İşte konuyla ilgili iyi bir okuma:

http://misko.hevery.com/code-reviewers-guide/flaw-digging-into-collaborators/

Son zamanlarda bu tür sorun ile boğuşuyor oldum. Depedency Enjeksiyon vs Hizmet Belirleme.

Ben gitmek için yolu gerektiği gibi, yapıcı bireysel ince taneli nesneleri enjekte etmek olduğunu Mark katılıyorum. Tek dezavantajı, Mark vurgulanmış olduğu gibi, karmaşık bir nesne grafiği oluştururken, kaçınılmaz başlamak zorunda olduğunu somewhere. Bu yüksek seviye nesneleri lots onlara enjekte hizmetleri (nesneleri) sahip olacağı anlamına gelir.

Bu turda kolay yolu sizin için zor işi yapmak için bir şey kullanmaktır. Bu örnektir şeyleri gidiş çok iyi bir yol gibi geliyor bana hangi Google'ın Guice olduğunu. Ne yazık ki Java için yazılmış! Yaklaşık PHP versiyonları vardır; Ben bunlardan herhangi oldukça bu noktada Guice kadar ölçmek emin değilim.

Ben bir post on this topic ki daha ayrıntılı gider yazdım; ilginç bulmak olabilir. Bu dependency injection framework basit bir uygulama içerir.

Alt satırda bir sınıf Foo gereksinimleri bir dizi var ise, gibi sizin sınıf oluşturabilirsiniz olmasıdır:

/**
 * Depends on db, logger and foomodel.
 */
class Foo
{
    private $db;
    private $logger;
    private $fooModel;

    /**
     * (other documentation here)
     * @inject
     */
    public function __construct(IDbService $db, ILoggerService $logger, $iModelService $model)
    {
       // do something
    }
}

Eğer yeni bir Foo nesne, istediğiniz zaman basitçe bağımlılık enjeksiyon çerçeve sormak create you one:

$foo = $serviceInjector->getInstance('Foo');

Bağımlılık enjektör emin bağımlılıkları enjekte yapma, zor işleri yapacaktır. Mantıklı eğer bu bağımlılıkları herhangi bağımlılıkları içerir. Diğer bir deyişle o ağacın kadar yinelemeli tüm dışarı sıralamak.

Eğer bir IBarService nesne gerekir bulmak Daha sonra, sadece herhangi bir diğer kod değiştirmeden, construtor ekleyebilirsiniz!