Семантически говоря, я думаю, что вариант 1 имеет смысл, если вы рассматриваете БД как ресурс, тогда DB_Connectioin - это объект, который он использует, но не обязательно сам объект.
Однако, несколько вещей, против которых я вас предостерегаю. Во-первых, не устанавливайте в своем классе БД все статические методы, так как это сильно повлияет на вашу способность тестировать код. Вместо этого рассмотрим очень простую инверсию управляющего контейнера:
class DB {
private $connection;
public function &query($sql) {
return $connection->query($sql);
}
public __construct(&$db_connection) {
$this->connection = $db_connection;
}
}
class Item {
public function &getList() {
return ResourceManager::getDB()->query("SELECT * FROM items");
}
}
class ResourceManager {
private $db_connection;
private function &getDbConnection() {
if (!$this->connection) {
$this->connection = new DB_Connection();
}
return $this->connection;
}
private $db;
public static function getDB() {
if(!$this->db) $this->db = new DB(getDbConnection());
return $this->db;
}
Существуют значительные преимущества. Если вы не хотите, чтобы БД использовалась в качестве одиночного, вы просто вносите одно изменение в ResourceManager. Если вы решите, что это не должен быть синглтон - вы вносите изменения в одном месте. Если вы хотите вернуть другой экземпляр БД на основе некоторого контекста - опять же, изменение происходит только в одном месте.
Теперь, если вы хотите протестировать Item в изоляции от БД, просто создайте метод setDb ($ db) в ResourceManager и используйте его для установки поддельной / фиктивной базы данных ( simplemock хорошо вам подойдет в этом отношении ).
Второе - и это еще одна модификация, которую облегчает этот дизайн - вы, возможно, не захотите, чтобы ваше соединение с базой данных оставалось открытым все время, в результате может потребоваться гораздо больше ресурсов, чем необходимо.
Наконец, как вы упоминаете, что DB_Connection имеет другие не показанные методы, похоже, что он может использоваться не только для поддержания соединения. Поскольку вы говорите, что не имеете над ним никакого контроля, я мог бы рекомендовать извлечь из него интерфейс из методов, о которых вы заботитесь, и сделать MyDBConnection расширяющим класс DB_Connection, который реализует ваш интерфейс. По моему опыту, что-то подобное в конечном итоге также ослабит боль.