我有一個類:記錄所有操作:良好的設計模式?
class Phone
{
public function addnewnumber ($name, $number)
{
}
}
現在讓我們想象一下,我要記錄所有的操作。我不想把Logger::add();
這樣的東西放在addnewnumber()
之內 - 也許它不可能修改那個類。那如何解決呢?
我有一個類:記錄所有操作:良好的設計模式?
class Phone
{
public function addnewnumber ($name, $number)
{
}
}
現在讓我們想象一下,我要記錄所有的操作。我不想把Logger::add();
這樣的東西放在addnewnumber()
之內 - 也許它不可能修改那個類。那如何解決呢?
在某些情況下,您可以使用包裝對象的代理類並允許您使用__call
轉發函數調用。這將是這個樣子:
class Proxy
{
private $_target;
public function __construct($target)
{
$this->_target = $target;
}
public function __call($name, $params)
{
$callable = array($this->_target, $name);
if (!is_callable($callable)) {
trigger_error('Call to undefined method '.
get_class($this->_target).'::'.$name, E_USER_ERROR);
}
return $this->dispatch($callable, $params);
}
protected function dispatch($callable, $params)
{
return call_user_func_array($callable, $params);
}
}
然後,您可以從這個類派生並重寫dispatch
執行自定義處理:
class LoggingProxy extends Proxy
{
protected function dispatch($callable, $params)
{
echo "Before calling ".get_class($callable[0]).'::'.$callable[1]."\n";
$return = parent::dispatch($callable, $params);
echo "After calling ".get_class($callable[0]).'::'.$callable[1]."\n";
return $return;
}
}
而且使用它像:
$proxy = new LoggingProxy(new Phone);
$proxy->addnewnumber(1, 2);
然而,這種方法確實有一些缺點:
Proxy
周圍,而不是Phone
)您無法在每個類的每種方法上自動調用某些日誌記錄功能。如果您想將日誌記錄添加到手機的addnewnumber方法中,而不更改類本身,則可以將其擴展到您自己的類中。
class Phone
{
public function addnewnumber($name, $number)
{
}
public function somethingelse()
{
}
}
class MyPhone extends Phone
{
public function addnewnumber($name, $number)
{
Logger::Add();
parent::addnewnumber($name, $number);
}
}
現在您的MyPhone類有所有的手機的方法,但是調用addnewnumber方法時,它記錄的數量,然後調用的實際方法。
那麼方法的參數必須遵循擴展類,是不是那種「過勞」? –
請參閱http://stackoverflow.com/questions/1603469/php-how-to-pass-child-class-construct-arguments-to-parent-construct發送動態參數。但是,是的,它總是有一些工作。但這就是它在PHP中的方式。 –