我对这个神秘的标题感到非常抱歉,但我真的不知道如何用简短的标题风格来形容它。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