Я отправлюсь с вами в путешествие, чтобы объяснить некоторые принципы проектирования, которые помогут нам организовать, очистить нашу кодовую базу и сделать ее более расширяемой и сопровождаемой. Итак, давайте рассмотрим важные концепции, которые делают наш код более чистым и пригодным для повторного использования.
Что такое композиция и когда мы должны ее использовать?
Позвольте мне объяснить и ответить на этот вопрос на примере, мы все любим примеры 🙂
Представьте, что у вас есть суперкласс под названием Duck
class Duck
{
public function fly(){}
public function quack(){}
public function display(){}
}
У этого класса есть 3 обычных метода, и это хорошо на данный момент, и это хорошо работает для нас, пока ваш клиент не попросит добавить новый тип утки под названием RubberDuck, здесь вы заметите проблему?
Давайте посмотрим на проблему
class RubberDuck extends Duck
{
public function fly(){} // Why implement this method ?!
public function quack(){} // also why too ?!
public function display(){}
}
Когда вы расширяете родительский класс Duck, вы наследуете методы fly() и Quack(), которые бесполезны для Rubber Duck, так какое же решение? Ответом будет вытащить методы fly и Quack за пределы класса Duck и сделать новый интерфейс под названием что-то вроде FlyableInterface и QuackablInterface, которые оба имеют один метод, например, называется fly() в FlyableInterfance и quack в QuackablInterface, после чего класс Duck может реализовать методы этих интерфейсов на основе своей функции.
Таким образом, код будет рефакторизоваться следующим образом
Interface Flyable
{
public function fly();
}
Interface Quack
{
public function quack();
}
Теперь новая версия класса RubberDuck будет реализовывать новый метод интерфейса
class RubberDuck implements FlyableInterface, QuackableInterface
{
public function fly(){} // from interface
public function quack(){} // from interface
public function display(){}
}
и класс Duck имеет один метод, общий для всех типов, который называется display()
class Duck
{
public function display(){}
}
Так что здесь мы частично решили проблему, но после этого обновления мы также заметим некоторые проблемы, но давайте обсудим это в других статьях или напишем ваши комментарии о проблемах.
Итак, из приведенного выше примера мы можем обобщить смысл композиции, сказав, что это процесс извлечения некоторых методов из класса и создания интерфейсов, чтобы позволить этому классу реализовать методы подходящих интерфейсов, а не все методы из суперкласса.
Я надеюсь, что мне удалось прояснить идею, даже в простой форме.
Спасибо за прочтение и извините за мой английский, так как это не мой язык.