interface DoSomething
{
public function do();
public function getId();
}
class DoSomethingGood implements DoSomething
{
private $dependency;
private $id;
public function __construct($id, $dependency)
{
$this->dependency = $dependency;
$this->id = $id;
}
public function do()
{
if ($this->dependency->isActive()) {
return true;
}
return false;
}
public function getId()
{
return $this->id;
}
}
class DoSomethingBad implements DoSomething
{
private $id;
public function __construct($id)
{
$this->id = $id;
}
public function do()
{
return false;
}
public function getId() {
return $this->id;
}
}
我应该在这里使用组合还是继承会更好? 区别在于这些类如何实现 do()
方法。 第一个类具有它所需的依赖关系和一些内部逻辑来决定,而另一个类则更简单。
继承是一种语义关系。不是构图。一个常见的错误是通过使用继承而不是组合来分解代码。
只见利斯科夫替换原理
我认为你应该从概念上考虑这段代码。这些类之间的关系是什么?是关系还是有关系?
如果可以说DoSomethingGood
是DoSomething
,那么继承很好地反映了这一点。您可以让继承器替换继承的类和适当的多态性。应用程序的其余部分将很好地通过此选择进行,因为它反映了您对此的看法。
如果你可以说DoSomething
有DoSomethingGood
那么你应该使用构图。特别是如果你可以有很多DoSomethingGood
.同样,如果这在概念上是正确的,则其余代码很容易编写。
有时看起来你可以对两者都说"是",并且线条模糊,但你应该真正在概念级别考虑它,而不是在代码级别。特别是如果你想理解模式,而不仅仅是"代码重用",这是一种关于继承的推理方式。
当你的选择错误时,编码将变得繁琐、违反直觉、不必要的复杂或完全不可能(矛盾)。如果发生这种情况,请回到绘图板并重新考虑您的选择。
也就是说,你几乎是唯一一个可以说出你的想法和你想做什么的人。如果您使用像DoSomethingGood
这样的名称,那就模棱两可了。
当你说Cat
、Dog
和Animal
时,要容易得多。在这里很容易说出使用什么(断言"Cat
是一个Animal
"在直觉上是正确的)。