Чого забагато для передачі даних за допомогою ін’єкції залежностей?
Тема впровадження залежностей вже деякий час обговорюється в колах об’єктно-орієнтованого програмування. Іноді ми бачимо це в WordPress; іноді ми цього не робимо.
Я прихильник цього, але, чесно кажучи, я не завжди впевнений, скільки інформації вводити в клас. Я маю на увазі, скажімо, нам дають два класи, і один містить інформацію, необхідну іншому.
- Чи ми не вставляємо клас в інший клас?
- Чи вводимо ми лише частину інформації (будь то рядок, ціле число, структура даних чи щось інше) в інший клас?
Я не думаю, що для цього існує жорстке правило, але можна з упевненістю сказати, що краще вводити лише ті дані, які вам потрібні. Але тоді виникає питання про те, як підготувати дані для введення в певний клас?
- Ви створюєте метод в одному класі та передаєте його в інший?
- Чи передаєте ви в нього частину приватної чи захищеної інформації?
Знову ж таки, я думаю, що це залежить від того, чи має щось статися з інформацією, перш ніж її передадуть у клас.
У будь-якому випадку, я міг би продовжувати це до кінця публікації і ніколи не дійти висновку, тож чому б не попрацювати над вихідним кодом, доки не буде чогось розумного.
Давайте почнемо з того, що у нас є основний файл класу плагіна, і цей клас відповідає за збереження такої інформації, як:
- шлях до плагіна,
- URL до плагіна,
- чи завантажено плагін,
- екран, який зараз переглядається,
- і класи, яким потрібно транслювати (думаю, pub/sub) певну інформацію.
Можливо, скелет або заглушка класу може виглядати так :
<?php
class Plugin
{
protected $plugin_path;
protected $plugin_url;
private $loaded;
public function __construct($file)
{
$this->loaded = false;
$this->plugin_path = plugin_dir_path($file);
$this->plugin_url = plugin_dir_url($file);
}
public function isLoaded()
{
return $this->loaded;
}
public function load()
{
// ...
}
private function isCurrentAdminStatus()
{
// ...
}
public function getSubscribers()
{
return [
new OtherPluginClass(...)
];
}
}
Тоді давайте почнемо дуже широко. Скажімо, ми хочемо взяти весь клас і передати його в один із класів, якому він транслює інформацію.
Якби це було так, то це могло б виглядати так :
<?php
class Plugin
{
protected $plugin_path;
protected $plugin_url;
private $loaded;
public function __construct($file)
{
$this->loaded = false;
$this->plugin_path = plugin_dir_path($file);
$this->plugin_url = plugin_dir_url($file);
}
public function isLoaded()
{
return $this->loaded;
}
public function load()
{
// ...
}
private function isCurrentAdminStatus()
{
// ...
}
public function getSubscribers()
{
return [
new OtherPluginClass($this)
];
}
}
Але одна з проблем полягає в тому, що він передає набагато більше інформації, ніж потрібно, в інший клас. Крім того, він передає інформацію, яка включає інформацію про клас, до якого він передає інформацію.
Отже, припустімо, ми хочемо зробити крок назад і просто передати одну з приватних частин інформації. Це просто, правда? У підсумку це виглядає приблизно так :
<?php
class Plugin
{
protected $plugin_path;
protected $plugin_url;
private $loaded;
public function __construct($file)
{
$this->loaded = false;
$this->plugin_path = plugin_dir_path($file);
$this->plugin_url = plugin_dir_url($file);
}
public function isLoaded()
{
return $this->loaded;
}
public function load()
{
// ...
}
private function isCurrentAdminStatus()
{
// ...
}
public function getSubscribers()
{
return [
new OtherPluginClass($this->plugin_path)
];
}
}
І цього може бути цілком достатньо для деяких випадків. Але, як згадувалося раніше, бувають випадки, коли ми хочемо взяти інформацію, обробити її, а потім передати в клас.
Щоб зробити це, ми просто визначимо метод, попросимо його обробити інформацію, а потім передамо повернуте значення в клас, якому потрібна інформація :
<?php
class Plugin
{
protected $plugin_path;
protected $plugin_url;
private $loaded;
public function __construct($file)
{
$this->loaded = false;
$this->plugin_path = plugin_dir_path($file);
$this->plugin_url = plugin_dir_url($file);
}
public function isLoaded()
{
return $this->loaded;
}
public function load()
{
// ...
}
private function isCurrentAdminStatus()
{
// ...
}
public function getSubscribers()
{
return [
new OtherPluginClass($this->isCurrentAdminStatus())
];
}
}
Ідея цього обговорення виникла під час роботи над переглядом коду нещодавнього проекту та обговорення різних варіантів, за допомогою яких інформація може бути передана в клас.
Тож я почав широко (незважаючи на те, що є необхідним, навіть зважаючи на процес мислення вище), а потім звузив його до лише необхідного.