我在設計類時遇到了兩難的問題。 我盡我所能去尊重SOLID原則,但我不知道如何處理依賴注入。如何在一個完整的面向對象應用程序中處理依賴注入
這裏是我的困境:
- 我讀這是一個不好的做法來實例化內部類的對象,以避免產生依賴。那麼我們的依賴應該在完整的對象應用程序中創建?在只負責依賴實例的特殊對象中?如果是的話,這個對象的名字是什麼,以及如何定義它?是我們所說的「控制器」嗎?
- 這個「控制器」,單元測試的正確方法是什麼?我們應該單元測試它嗎?
- 在完整的POO應用程序中,如何避免在類之間傳遞對象(通常是相同的)?例如,一個DB對象Log,...通過這種方式,我們冒險讓構造函數有很多參數,不是嗎?
爲了說明我的困境,我試圖創建一個用例。
我想創建生成文件的腳本(我在下面部分實現)和打印另一個問題:
<?php
/**
* Generate a file, add it to the queue and print the next one
*/
class Script
public function run() {
#Generate file
$fileComputor = new FileComputer(...);
$file = $fileComputor->compute();
#Instantiate dependencies for printing
$db = new Db(new PdoAdapter());
$printerDriver = new Driver(new HttpRequest(new CurlAdapter()));
$log = new Log($db);
$queue = new Queue($db);
$statsUpdater = new StatsUpdater($db);
$monitor = new Monitor(new StatsdDriver(new SocketAdapter()));
#Add generated file to the queue
$queueModel->push($file);
#Print the next file on queue if existing
$printer = new Printer($printerDriver, $log, $queue, $monitor, $statsUpdater);
$printer->print();
}
}
class Printer {
protected $_driver;
protected $_log;
protected $_queue;
protected $_monitor;
protected $_statsUpdater;
/**
* $driver : Driver used to send documents to the printer
* $log : Log actions in database
* $queue : Handle the print queue
* $monitor : Send metrics to Statsd (to feed the graphit GUI)
* $statsdUpdater : Consolidate the statistics database
*/
public function __construct($driver, $log, $queue, $monitor, $statsUpdater) {
$this->_driver = $driver;
$this->_log = $log;
$this->_queue = $queue;
$this->_monitor = $monitor
$this->_statsUpdater = $statsUpdater;
}
public function print() {
if ($this->_queue->hasNext()) {
$file = $this->_queue->getNext();
$this->_driver->print($file);
$this->_log->log('File has been printed');
$this->_monitor->sendCount(1);
$this->_statsUpdater->increment();
}
}
}
?>
你覺得這個怎麼樣實現?
我們希望插入到我們的Printer類中的每個功能都會導致傳遞給構造函數的新依賴項(例如,如果我們還想生成syslog,測量打印機處理的時間等) 。
在不久的將來,我們將有10到15個參數進入構造函數調用。
你'腳本'類有什麼意義?這不是Java,你不需要在「僅僅因爲」類中包裝腳本。 –
這是PHP。事實上,我調用了Script類,因爲它實際上擴展了一個ScriptAbstract類(能夠處理參數並打印一個用例示例),但我沒有將它精確化,以免混淆。在真實情況下,類使用傳遞給腳本的參數並將它們發送到FileComputer和Printer類。 –