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
«интуитивно правильно).