私は非常識なタイトルのために申し訳ありませんが、私は正直なところ、短いタイトルスタイルの方法でそれを表現する方法を知らない。PHP:この場合、SOLID原則に違反することなく拡張インターフェースを使用する方法は?
最初の短いバージョン。簡単な電子メールの確認の仕組み。 1つの方法は、確認リンク付きで電子メールを送信することです。リンクをクリックすると、別のコントローラが第2のメソッドを呼び出し、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
@ CD001渡されたオブジェクトに強制的にインターフェイスを実装させます。そうしないと、PHPによってエラーがスローされます。 –
@FélixGagnon-Grenierは実際に動作しますか? – CD001