我對這個神祕的標題感到非常抱歉,但我真的不知道如何用簡短的標題風格來形容它。PHP:如何在不違反SOLID原則的情況下使用擴展接口?
首個簡短版本。簡單的郵件確認機制。一種方法是發送帶確認鏈接的電子郵件。點擊鏈接後,另一個控制器調用第二個方法,該方法從URL中驗證令牌。在兩個動作之間ConfirmationObject正在被存儲,包括令牌和其他可能的數據。成功確認使用「successHandler」後。
簡化代碼:
interface SuccessHandlerInterface {
public function success(ConfirmationObjectInterface $object);
}
class EmailTester {
public function try(ConfirmationObjectInterface $object) {
// some code
}
public function confirm($token) {
$confirmationObject = $this->repository->findByToken($token);
$type = $confirmationObject->getType();
$successHandler = $this->handlersRegistry->getSuccessHandler($type);
$successHandler->success($confirmationObject);
}
}
現在,我們將使用這種方式:
// Firstly let's implement our own success handler.
class UserRegistrationSuccessHandler implements SuccessHandlerInterface {
public function success(ConfirmationObjectInterface $object) {
// Do some stuff on success.
}
}
// Then let's register this success handler to be available in our `handlersRegistry` object.
$handlersRegistry->addType('user_registration', new UserRegistrationSuccessHandler());
// Now we will extend ConfirmationObjectInterface
interface RegistrationConfirmationObjectInterface extends ConfirmationObjectInterface {
public function getSomeDataGivenOnRegistration();
}
// And at the end, let's try our email
$confirmationObject = new RegistrationConfirmationObject(); // Which implements above interface.
// $confirmationObject->getType() === 'user_registration'
$emailTester->try($confirmationObject);
// Now confirmation link with token is being sent to the given email. If user will click it, below method will be invoked.
$emailTester->confirm($token);
現在的問題是,我寧願希望有RegistrationConfirmationObjectInterface
中可用的成功處理程序,而比ConfirmationObjectInterface
。
我知道我可以做:
// Firstly let's implement our own success handler.
class SuccessHandler implements SuccessHandlerInterface {
public function success(ConfirmationObjectInterface $object) {
if ($object instanceof RegistrationConfirmationObjectInterface) {
// Do stuff
}
}
}
但感覺不好。此檢查是毫無意義的,因爲$object
將始終是RegistrationConfirmationObjectInterface
的一個實例。這種設計有何缺陷,以及如何改進?
我可能會在這裏得到錯誤的結尾,但是你沒有實例化接口,所以這種事情對我來說沒什麼意義:'公共函數成功(ConfirmationObjectInterface $ object)'< - 是一個接口或對象(類實例)? – CD001
@ CD001它強制傳遞的對象來實現接口,否則php會拋出一個錯誤。 –
@FélixGagnon-Grenier確實有效嗎? – CD001