怎么做?
我有一个Model类,它是许多子类的父类,而Model依赖于数据库连接和缓存机制。
现在,这就是它开始变得麻烦的地方:我无法控制每个对象如何被实例化或使用,但我可以控制子类使用的方法。
目前我已经使用静态方法和属性进行依赖注入:
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; } }
哪个效果很好,但感觉很脏(它为所有模型创建了一个全局状态)。
我已经考虑了工厂模式,但是从子类中删除了实例化的控制(如何在其构造函数中实例化具有可变数量参数的对象?)。
现在我不知所措。任何帮助将不胜感激。
答案 0 :(得分:1)
据我所知,这是一个完全可以接受的选择。 PHPUnit的创建者Sebastian Bergmann建议的另一种可能性是使用$测试静态属性。你可以阅读他最近关于Testing of Singletons的文章。听起来你有类似的问题。
答案 1 :(得分:0)
您的解决方案可以设置默认适配器,但我会为各个型号添加一种方法来使用不同的适配器。考虑一下:
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;
}
}
当然,您可以将所有静态方法/属性提取到Registry
,Container
或其他任何内容中。
例如,您可能不希望在整个应用程序中从同一数据库主机收集数据。然后您的原始脚本将如下所示:
Model::setDatabaseAdapter($default);
$my_model->query('....');
Model::setDatabaseAdapter($another_adapter);
$my_other_model->query('....');
Model::setDatabaseAdapter($default);
非常相似:
mysql_select_db('default_db');
mysql_query('...');
mysql_select_db('other_db');
mysql_query('...');
mysql_select_db('default_db');