【发布时间】:2016-07-22 15:44:24
【问题描述】:
我很抱歉这个神秘的标题,但老实说,我不知道如何用简短的标题风格来描述它。
第一个短版。简单的电子邮件确认机制。一种方法是发送带有确认链接的电子邮件。单击链接后,另一个控制器调用第二个方法,该方法验证来自 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 的一个实例。这种设计有什么缺陷,如何改进?
【问题讨论】:
-
我可能在这里搞错了,但你没有实例化接口,所以这种事情对我来说没有多大意义:
public function success(ConfirmationObjectInterface $object) -
@CD001 强制传入的对象实现接口,否则php会报错。
-
@FélixGagnon-Grenier 这真的有效吗?
-
是的,在编写接口时,编码实际上开始变得有趣。有助于解耦代码,通常对 karma 有好处;)
-
以及多种形式的RegistrationConfirmation如何?
标签: php oop interface liskov-substitution-principle