我有一些处理程序("控制器")类,他们可以以某种方式处理项目:
interface IHandler { public function execute(Item $item); } class FirstHandler implements IHandler { public function execute(Item $item) { echo $item->getTitle(); } } class SecondHandler implements IHandler { public function execute(Item $item) { echo $item->getId() . $item->getTitle(); } } class Item { public function getId() { return rand(); } public function getTitle() { return 'title at ' . time(); } }
但是我需要在子Item类中添加一些新功能:
class NewItem extends Item { public function getAuthor() { return 'author ' . rand(); } }
并在SecondHandler中使用它
class SecondHandler implements IHandler { public function execute(Item $item) { printf('%d %s, author %s', $item->getId(), $item->getTitle(), $item->getAuthor()); } }
但是Item
班级实际上并没有getAuthor
方法.并且,如果我尝试在SecondHandler
类中更改accept方法的签名,我将捕获E_STRICT
有关声明兼容性的错误.当然,这是一种LSP违规.
我该如何解决这个问题?例如,我是否需要两个接口,INewHandler
并且IHandler
具有不同的execute
方法签名?但它是某种代码重复.
此外,我不能使用__constructor(Item $item)
和__construct(NewItem $item)
处理程序(以及execute
没有参数的方法),这将被视为更好的解决方案:它们必须是不可变的,并且在应用程序生命周期中只允许每个策略的单个实例.