2016-04-20 74 views
2
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()方法。第一类具有它所需要的依赖性和一些内部逻辑来决定,而另一类更简单。组成或继承

回答

1

我想你应该从概念上思考这个代码。这些类之间的关系是什么?是否is-a relationship or has-a relationship?

如果你可以说DoSomethingGoodDoSomething,那么继承反映得很好。您可以让继承者替换继承的类和适当的多态。其他应用程序在选择时会流畅运行,因为它反映了您对此的看法。

如果你可以说DoSomething有一个DoSomethingGood那么你应该使用组合。特别是如果你可以有很多DoSomethingGood。再次,如果这在概念上是正确的,那么其余的代码很容易编写。

有时看起来你可以对两者都说“是”,线条模糊,但你应该在概念层面而不是在代码层面考虑它。特别是如果你想了解模式,而不仅仅是“代码重用”,这是一种关于继承的微妙推理方式。

当你的选择错误时,编码将变得笨拙,违反直觉,不必要地复杂或不可能(矛盾)。如果发生这种情况,请回到制图板并重新考虑您的选择。

这就是说,你几乎是唯一可以说出你想要什么以及想做什么的人。如果你使用DoSomethingGood这样的名字,它是不明确的。

当你说Cat,DogAnimal时,它会容易得多。这里很容易说出使用什么(断言“CatAnimal”是直觉上正确的)。

2

继承是一种语义关系。不是组成。一个常见的错误是通过使用继承而不是组合来分解代码。

只看到Liskov substitution principle

+0

惊人的洞察力,请把一些链接到书,你在你的个人喜欢的文章,我真的不知道有什么可以做一个这样想。 – Arjang

+1

@Arjang看看面向对象设计的基本原则:[SOLID](https://en.wikipedia.org/wiki/SOLID_(object-oriented_design)) – pid