Я очень стараюсь понять Dependency Injection и как избежать глобальных изменений в рамках бэкэнда проекта веб-сайта.Здесь я использую PHP.
// MySQLDatabase.php
class MySQLDatabase
{
private $database;
public function __construct($db_host, $db_username, $db_password, $db_name) {
$this->database = new mysqli(
$db_host,
$db_username,
$db_password,
$db_name
);
}
}
// User.php
class User {
public function __construct($database, $id);
}
// Image.php
class Image {
public function __construct($database, $id);
}
$database = new MySQLDatabase($dbh, $dbu, $dbp, $dbn);
$existingUser = new User($database, $userID);
$existingImage = new Image($database, $imageID);
Я понимаю, что для того, чтобы код был тестируемым, содержательным и без глобальных переменных, мне нужно вводить зависимости.Где я запутался, это , где , чтобы создать эти зависимости.Похоже, что на каждый вопрос о внедрении зависимостей отвечает приведенный выше код, и они говорят: «Вот как вы это делаете!Но они никогда не объясняют, как настроить остальную часть вашей программы так, чтобы зависимости могли быть связаны вместе.
Сначала я подумал об использовании файла начальной загрузки, который сначала создает зависимости для остальной части программы:
// bootstrap.php
$database = new MySQLDatabase($dbh, $dbu, $dbp, $dbn);
Но мне кажется, что я просто создаю глобал здесь.Почти каждой моей странице понадобится база данных, и эта база данных будет передаваться по каждому сценарию ... Мне кажется, что это одиночка (от которой все также говорят, что нужно избегать).
Я мог бы создать базу данных в любом месте, где мне это нужно, на каждой странице.Это означало бы, что страница user.php не будет использовать файл начальной загрузки, а будет просто извлекать необходимые ей зависимости (база данных, пользовательские классы и т. Д.).И это будет происходить на каждой странице (user_images.php, login.php).Но это похоже на повторение кода, потому что на каждой странице будет один и тот же код.Я также подумал о создании класса статического типа, который бы упростил создание экземпляра базы данных, которую вы можете загрузить через файл:
// MySQLDatabase.php
class SpecificDatabase
{
private static $initialized = false;
public static function initialize($db_host, $db_username, $db_password, $db_name) {
if(self::$initialized) return;
self::$database = new MySQLDatabase(
$db_host,
$db_username,
$db_password,
$db_name
);
self::$initialized = true;
}
}
Но в этом случае вам всегда нужно будет получить БДучетные данные для инициализации базы данных каждый раз, когда вы хотите ее использовать (если вы не жестко закодировали ее здесь, но я думаю, что это так же плохо).По всему моему коду почти на каждой странице было написано следующее:
require_once(__DIR__.'/vendor/autoload.php');
require_once(__DIR__.'/utilities/database/SpecificDatabase.php');
require_once(__DIR__.'/entities/User.php');
// load environment variables
$dotenv = new Dotenv\Dotenv(__DIR__);
$dotenv->load();
$database = new SpecificDatabase(getenv('DATABASE_HOST'), getenv('DATABASE_USERNAME'), getenv('DATABASE_PASSWORD'), getenv('DATABASE_NAME'));
$user = new User($database, $userID);
Может ли кто-нибудь помочь мне лучше понять это?Я действительно хочу быть великим программистом.Есть только некоторые препятствия, которые уводят меня намного дольше, и я думаю, что это может привести к некоторым простым недоразумениям, особенно словарному запасу - например, я думаю, что я заблокирован парадоксом избегания повторения И избегать глобалов.Большая часть моего исследования внедрения зависимостей сводится к выводу извлечения зависимостей из классов.Но когда их вытаскивают, куда они идут ...?