我正在重新分解大量代码以使其更易于测试,并且我有许多依赖于实例化数据库对象的有用函数。
这样的事情:
function id_from_name($table, $name)
{
$db = get_database();
//code that returns an id
}
function username_from_user_id($id)
{
$db = get_database();
//code that returns a username
}
有一些更像id_exists,id_active等。
现在我认为这不是正确的事情,因为对象应该作为参数传递?但这意味着每次我想使用一个新对象时,都会创建并发送新对象。
所以,我的问题是:我是否应该将这些函数移动到可以访问数据库对象的自己的类/库中?我上面展示的例子通常是一种糟糕的做事方式吗?
答案 0 :(得分:4)
更好的方法是制作课程。您将把数据库对象传递给构造函数并使其成为实例变量。这样每个函数都可以访问数据库对象。
现在认为实例化例如不好的原因是每个函数中的数据库对象,是因为如果您决定有一天更改数据源,则可能需要一个巨大的重构器。如果将数据库对象传递给构造函数,则可以在没有任何重构的情况下将正确的对象传递/注入类中。
...关于DI的更多信息......
通过将对象传递给构造函数,您还可以创建更清晰的API =>你知道哪个对象依赖于另一个对象,你确切知道哪个类使用你的DB对象。如果你开始实例化它或者像你一样在函数内部以静态方式访问它,我将不得不浏览所有类来查看数据库对象的使用位置。还有一点,依赖注入力SRP(单一责任原则)=>如果你开始注入太多的对象(构造函数得到很多参数),你应该怀疑你的类做得太多了,并开始重构。
答案 1 :(得分:0)
您可以创建一个类Table_Adapter
并在其构造函数中实例化数据库对象:
class Table_Adapter
{
protected $db;
public function __construct()
{
$db = get_database();
}
}
然后创建子类Items_Table_Adapter' that extends
Table_Adapter and put their all methods related to
Items`表。
class Items_Table_Adapter extends Table_Adapter
{
public function item_by_id($id)
{
}
}
然后你就像使用它一样:
$tableAdapter = new Items_Table_Adapter();
$item = $tableAdapter->item_by_id(1);
答案 2 :(得分:0)
尝试类似:
class YourClass{
public static function get_database(){
// your creation
return $db;
}
public function id_from_name($table, $name)
{
/* your code */
//code that returns an id
}
public function username_from_user_id($id)
{
/* your code */
}
}
所以你可以这样使用它:
$db = YourClass::get_database();
$result = $db->id_from_name($table, $name);
答案 3 :(得分:0)
当然建议您可以选择换出数据库连接。
现在,如果您的函数get_database()
如下所示:
function get_database() {
static $db;
if (!$db)
$db = new \mysqli(...);
return $db;
}
然后你真的,真的应该把它改成一个类的包装器,看起来像这样:
function get_database_manager() {
static $dbmgr;
if (!$dbmgr)
$dbmgr = new DbManager;
return $dbmgr;
}
function get_database() {
return get_database_manager()->getCurrentConnection();
}
其中DbManager
的实例属性包含getCurrentConnection()
返回的当前连接。如果要换出连接,请执行get_database_manager()->setConnection($newConn)
之类的操作。问题解决了:))
我将在这里留下静态编程的缺点(在这个帖子中有很多例子):http://kunststube.net/static/ 以及摆脱它的常用方法(我们在这里有另一种方法):http://en.wikipedia.org/wiki/Dependency_injection