当前位置:  开发笔记 > 编程语言 > 正文

Liskov替换原则和使用继承类的正确方法

如何解决《Liskov替换原则和使用继承类的正确方法》经验,为你挑选了0个好方法。

我有一些处理程序("控制器")类,他们可以以某种方式处理项目:

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没有参数的方法),这将被视为更好的解决方案:它们必须是不可变的,并且在应用程序生命周期中只允许每个策略的单个实例.

推荐阅读
跟我搞对象吧
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有