Много раз я слышал, чтобы избежать статических классов, потому что они будут вставлять зависимости, которые сделают ваш код непригодным для использования в других проектах и не позволят ему его протестировать .
Допустим, у нас есть типичная class DB
для доступа к базе данных, если такой класс является static
мы могли бы называть его везде в нашем коде:
DB::execQuery(...);
но это создает зависимости, поэтому давайте сделаем класс базы данных НЕ статическим, в таком случае мы будем иметь где-то в нашем коде:
$db = new DB();
и тогда мы могли бы позвонить в наш код
$db->execQuery(...);
Но теперь, когда мы используем $db
внутри function
нам нужно каждый раз сначала объявить ее так
global $db;
Есть ли способ обхода этого?
Один из способов может заключаться в том, чтобы $db
объект $db
в класс, который его использует, но мне пришлось бы вводить его во все классы, которые его используют, это смехотворно, статический класс будет намного быстрее работать с и меньше кода для записи. Я что-то упускаю?!
$ db может быть введено при создании в свойство, тогда вам нужно будет получить доступ к этому свойству, а не передавать его каждому методу.
class MyClass { protected $_db; // DB Connection public function __construct($db) { $this->_db = $db; } public function foo() { $this->_db->query('...'); } }
Помимо этого, вы можете изучить наличие контейнера-службы (ака-контейнера зависимости), который пытается действовать как глобальная переменная, но решает некоторые проблемы тестирования. Взгляните на некоторые из этих связанных вопросов
Наличие контейнера DI позволяет использовать статические методы в ваших классах, таких как DI_Container::get('db')
. Он очень похож на global
или некоторые другие статические вызовы .. но в этом случае DI_Container
содержит специальные методы, которые позволяют принимать дополнительные меры во время тестирования и в других обстоятельствах .. устранение некоторых «злобности» глобального.
В дополнение к ответу Майка Б, я бы указал, что неправильный дизайн в вашем коде: «мы могли бы называть его везде, где в нашем коде».
Фактически, база данных должна использоваться только вашей моделью или малой частью вашего приложения, которая должна знать о базе данных. Поэтому эти классы должны знать, что есть база данных, и использовать ее как зависимость (передается через конструктор, как сказал Майк Б).
Но остальная часть вашего приложения не должна заботиться о базе данных, ее следует заботиться только о модели. Сосредоточьтесь на рефакторинге и сборе всего кода, который обращается к базе данных в классах модели.
Таким образом, ваше приложение будет иметь слой модели, который имеет зависимость: объект / соединение с базой данных. Остальная часть вашего приложения будет использовать модель, независимо от того, что происходит в модели, ни в одном из бизнеса Controller / View.
Наслаждайтесь рефакторингом.