Eğer oluşturulabilmesi ve kullanımı üzerinde hiçbir kontrole sahip bağımlılık enjeksiyon

2 Cevap php

Nasıl yapılır?

Ben birçok alt sınıflara üst bir model sınıf var ve bu model bir veritabanı bağlantısı ve bir önbelleğe alma mekanizması bağlıdır.

Zahmetli almaya başlıyor Şimdi, bu nerede: Ben her nesne örneği veya alışmakta ne kadar üzerinde hiçbir kontrole sahip, ama alt sınıflar tarafından alışmak yöntemler üzerinde kontrole sahip.

Şu anda ben gibi, bağımlılık enjeksiyon için statik yöntemlerini ve özelliklerini kullanarak başvurdular:

class Model
{
    private static $database_adapter;
    private static $cache_adapter;
    public static function setDatabaseAdapter(IDatabaseAdapter $databaseAdapter)
    {
        self::$databaseAdapter = $databaseAdapter;
    }
    public static function setCacheAdapter(ICacheAdapter $cacheAdapter)
    {
        self::$cacheAdapter = $cacheAdapter;
    }
}

Iyi çalıştı, ancak (tüm modeller için küresel bir devlet oluşturur) kirli hissediyor hangi.

Ben fabrika desen kabul var, ama bu alt-sınıflar (nasıl ben bunu yapıcısında parametrelerin değişken sayısı ile bir nesne örneğini mi?) Gelen örnekleme kontrolünü kaldırır.

Şimdi ben bir kayıp am. Herhangi bir yardım mutluluk duyacağız.

2 Cevap

Bildiğim kadarıyla bu mükemmel kabul edilebilir bir alternatiftir. Sebastian Bergmann, PHPUnit yaratıcısı, tarafından önerilen bir başka olasılığı $ test statik özelliğe sahip olmaktır. Sen Testing of Singletons ile ilgili yaptığı son makaleyi okuyabilirsiniz. Benzer sorunları var gibi geliyor.

Sen çözüm varsayılan adaptörleri ayarı için iyi olurdu, ama ben farklı bir adaptörü var ayrı model için bir yol eklemek istiyorum. Bu düşünün:

abstract class Model {
    protected $_database_adapter;
    protected $_default_database_adapter;

    public function getDatabaseAdapter() {
        if(!$this->_database_adapter) {
            if(self::$_default_database_adapter) {
                $this->_database_adapter = self::$_default_database_adapter;
            } else {
                throw new Exception("No adapter set yet");
            }
        }
        return $this->_database_adapter;
    }

    public function setDatabaseAdapter(IDatabaseAdapter $databaseAdapter) {
        $this->_database_adapter = $databaseAdapter;
    }

    public static function setDefaultDatabaseAdapter(IDatabaseAdapter $databaseAdapter) {
        self::$_default_database_adapter = $databaseAdapter;
    }
}

Tabii ki Container veya merkezi gibi başka bir şey, bir Registry içine tüm statik yöntemleri / özellikleri ayıklamak.

Örneğin, belki de tüm uygulama üzerinde aynı veritabanı ana veri toplamak istemiyorum. Sonra orijinal komut aşağıdaki gibi görünecektir:

Model::setDatabaseAdapter($default);
$my_model->query('....');
Model::setDatabaseAdapter($another_adapter);
$my_other_model->query('....');
Model::setDatabaseAdapter($default);

hangi müthiş aynı olduğunu:

mysql_select_db('default_db');
mysql_query('...');
mysql_select_db('other_db');
mysql_query('...');
mysql_select_db('default_db');