Nasıl "Dependency Injection" kullanabilirsiniz

7 Cevap php

Ben bağımlılık enjeksiyon ve bunun yararına her zaman bahsediyoruz insanlar duymak, ama ben gerçekten anlamıyorum.

O "Ben argümanlar olarak her zaman veritabanı bağlantıları geçirmek" sorununa bir çözüm olmadığını merak ediyorum.

Bunun üzerine wikipedia girişini okuma çalıştı, ama ben sağlam açıklığa kavuşturmak için çalışıyor farkı anlayamıyorum böylece örnek Java ile yazılmış. (http://en.wikipedia.org/wiki/Dependency_injection).

Ben bu bağımlılık-enjeksiyon-in-php makale (http://www.potstuck.com/2009/01/08/php-dependency-injection/) okumak ve objektif bir nesneye doğrudan bağımlılıkları geçmek değil, ama oluşturulması ile birlikte bir nesnenin oluşturulmasını kordon altına gibi görünüyor it bağımlılıkları bulunuyor. Gerçi, bir kullanarak php fonksiyonları bağlamında bu uygulamak nasıl emin değilim.

Ayrıca, aşağıdaki Bağımlılık Enjeksiyon, ve ben bir fonksiyonel bağlamda bağımlılık enjeksiyon yapmaya çalışıyor rahatsız gerekir?

Sürüm 1: (ben oluşturmak, ama sevmiyorum kod tür, her gün)

function get_data_from_database($database_connection){
    $data = $database_connection->query('blah');
    return $data;
}

Versiyon 2: (bir veritabanı bağlantısı geçmek zorunda değil, ama belki de enjeksiyon bağımlılık değil mi?)

function get_database_connection(){
    static $db_connection;
    if($db_connection){
        return $db_connection;
    } else {
        // create db_connection
      ...
    }
}

function get_data_from_database(){
   $conn = get_database_connection();
   $data = $conn->query('blah');
   return $data;
}

$data = get_data_from_database();

Versiyon 3: (/ data "nesne" nin oluşturulması ayrı, ve veritabanı kodu hala, bu yüzden belki de bu bağımlılık enjeksiyon olarak saymak olacaktır?)

function factory_of_data_set(){
    static $db_connection;
    $data_set = null;
    $db_connection = get_database_connection();
    $data_set = $db_connection->query('blah');
    return $data_set;
}

$data = factory_of_data_set();

Herkes yöntem ve fayda-kristal netliğinde yapan iyi bir kaynak ya da sadece fikir var mı?

7 Cevap

Bağımlılık enjeksiyon "Ben kurucusuna biraz daha fazla parametre" için büyük bir kelimedir.

Bu küresellerle sevmediğimiz zaman awfull Singleton dalga önce yaptım:

<?php
class User {
    private $_db;
    function __construct($db) {
        $this->_db = $db;
    }
}

$db   = new Db();
$user = new User($db);

Şimdi, hile bağımlılıkları, böyle bir şey yönetmek için tek bir sınıfı kullanmak için:

class DependencyContainer 
{
    private _instances = array();
    private _params = array();

    public function __construct($params)
    {
        $this->_params = $params;
    }

    public function getDb()
    {
        if (empty($this->_instances['db']) 
            || !is_a($this->_instances['db'], 'PDO')
        ) {
            $this->_instances['db'] = new PDO(
                $this->_params['dsn'],
                $this->params['dbUser'], 
                $this->params['dbPwd']
            );
        }
        return $this->_instances['db'];
    }
}

class User
{
    private $_db;
    public function __construct(DependencyContainer $di)
    {
         $this->_db = $di->getDb();
    }
}

$dependencies = new DependencyContainer($someParams);
$user = new User($dependencies);

Size sadece bir sınıf ve daha fazla karmaşıklık düşünmek gerekir. Ancak, kullanıcı sınıfın diğer sınıflar sürü gibi günlük iletileri için bir şey gerekebilir. Sadece kullanıcı sınıfı için bağımlılık konteynerine bir getMessageHandler işlev eklemek ve bazı $this->_messages = $di->getMessageHandler(). Kodunuzu kalanı değiştirmek için hiçbir şey.

Sen symfony's doc üzerindeki bilgilerin bir sürü alırsınız

İlk örneği IS dependancy enjeksiyon, sen işlevi veritabanı nesnesi üzerinde bağımlılık enjekte edilir.

Sarah bu değil dedi, ama imo ben o sonraki seviyeye kadar olan bağımlılık enjeksiyon konteyner düşünüyor inanıyorum olduğunu:

http://components.symfony-project.org/dependency-injection/trunk/book/02-Dependency-Injection-Containers

Lütfen örneklerin hiçbiri bağımlılık enjeksiyon gibi bakmak, sürüm bir olsa da yakın. Bağımlılık enjeksiyon hizmeti (bir fabrika, bir test ya da olabilir ki bu ihtiyacı nesneleri ve bu hizmeti nesneleri örneğinin yaratıcısı tarafından geçirilen bir nesnenin yapıcısı bağımsız değişkenleri nesne yönelimli programlama kullanılan bir tekniktir bir bağımlılık enjeksiyon çerçeve).

Senin Eğer şablon desen düşünebilirsiniz sorunu hep bağlantı nesnesi geçen 'etrafında almak için. Şablon desen bu yinelenen kod bloklarının örnekleri arasında değişim sağlamak için temelde bir tekrarlanan kod bloğunun ortak bir parçası, ve soyut yöntemleri ile soyut bir temel sınıftır. Temelde baz kod bloğu bir şablon ve soyut yöntemler Ben şahsen Java benim veritabanı kaynak denetimi yapmak için şablon yöntem desen kullanmak doldurulması gereken boşlukları vardır.

Ben bu konuda kendimi (PHP Dependency Injection) arama çok yaptım ve benim sevme için çok bulamadı. Bir çok diğer dillerde (Google Guice - {[(0)];} Java Spring) için konu üzerine yazılmış olan, ama PHP için çok geçerli bulamadı. Ne olursa olsun dil Ancak zorluklar benzerdir.

Eğer söz konusu liste üç versiyonu tipik yaklaşım vardır. Sürüm 3 Ben endüstri gidiyor gördük hangi yöne yakın. Kendi sınıfının dışında bağımlı nesneleri oluşturma sorumluluğunu kaydırarak, size test kodu istedikleri gibi bunları işlemek için ücretsizdir. Ancak, bu yaklaşım ile karşılaşılan sorun hatta potansiyel alıcı nesne tarafından kullanılan olamaz Yapıcınızda bağımlı nesnelerin uzun zincirleri ile sonuna kadar, ama bir ikincil bağımlı nesne geçti olsun olmasıdır. Bu dağınık olur ve nereden geliyor ne bilgi kaybedersiniz.

@ Arkh ve mmmshuddup @ tarafından Bağımlılık Konteyner örnek harika bir başlangıç, ama ben yine de bu yaklaşım ile sınırlamaları bulundu. Ben geldi bunun üzerine nihai çözüm biraz Scala popüler Kek Kalıbı sonra modellenmiştir bir özel inşa çözüm oldu. Bu sizin kurucular her birine tek bir bağımlılık geçmesine izin verir ve size bağımlı nesnelerin per sınıfı varsayılan inşaatı tanımlamak sağlar. Bu bağımlılıkları varsayılan uygulamaları kontrolünü kaybetme, uzun yanı sıra bağımlılık zincirlerinden sizi kurtarır.

Ben sistem Dizel çağırdı ve onunla gerçekten çok mutlu oldum. Ben ilgilenen herkes için github kodunu yayınladı. Ben temel kullanım açıklanır yanı sıra soru üzerine daha ayrıntılı gider konuya yazdı blogdan kendisine alabilirsiniz. http://developers.blog.box.com/2012/02/15/introducting-diesel-php-dependency-injection/

Bağımlılık Enjeksiyon onlar bağımlı neden odaklanmak amacıyla 2 bileşenler arasındaki bağımlılık kaldırılması fikirdir.

Başka bir bileşen B hizmetlerini kullanmak için gereken bir bileşen A var Imagine

Eğer A içindeki B varlığını hardcode, o zaman A sames hizmetlerini kullanmak istediğiniz zaman sıkışmış, ancak başka bir bileşen tarafından uygulanacaktır.

Bu yüzden genellikle, sen B ve C uygulayacak bir hizmet arayüz tanımlamak, ve sen A kullandığınızda, gerekli arayüzü ile uyumlu nesneler ile beslemek emin olun.

Senin durumunda, sizin arayüzü sorgulama yapabilirsiniz hangi bir hizmet olduğunu düşünebilirsiniz.

İlk vaka Bağımlılık Enjeksiyon fikrine daha yakın olanıdır.

Ben aşağıdaki linki belki çok faydalı bulacaksınız, enjeksiyon bağımlılık için yararlı bir intro içerdiğini bulabilirsiniz.

http://components.symfony-project.org/dependency-injection/trunk/book/01-Dependency-Injection

Maybe you will find useful also this text from Martin Fowler's site. It is a bit old but clearly states the differences between three different kinds of dependency injection (depending on how it is started)

http://www.martinfowler.com/articles/injection.html