ООП Повторное использование без наследования: насколько это практично в реальном мире? - PullRequest
10 голосов
/ 14 февраля 2011

В этой статье описывается подход к ООП, который мне кажется интересным:

Что если объекты существуют в виде инкапсуляций и общаются через сообщения?Что если повторное использование кода не имеет ничего общего с наследованием, но использует композицию, делегирование, даже устаревшие вспомогательные объекты или любую технику, которую программист сочтет подходящей?Онтология не исчезает, но она отделена от реализации.

Идея повторного использования без наследования или зависимости от иерархии классов - это то, что мне показалось наиболее поразительным, но насколько это осуществимо?

Были приведены примеры, но я не совсем понимаю, как я могу изменить свой текущий код, чтобы адаптировать этот подход.

Итак, насколько осуществим этот подход?Или действительно не нужно менять код, а использовать подход, основанный на сценариях, где «использовать только при необходимости или оптимально»?

РЕДАКТИРОВАТЬ: упс, я забыл ссылку: здесь она ссылка

Ответы [ 4 ]

8 голосов
/ 14 февраля 2011

Я уверен, что вы слышали о "всегда предпочитайте композицию наследованию".

Основная идея этого предположения состоит в том, что несколько объектов с различными функциональными возможностями объединяются для создания одного полнофункционального объекта. Это должно быть предпочтительнее, чем наследование функциональности от разрозненных объектов, которые не имеют ничего общего друг с другом.

Основной аргумент в этом отношении содержится в определении Принципа замены Лискова и игриво проиллюстрирован этим плакатом:

Liskov Substitution Principle: If it looks like a duck, quacks like a duck, but needs batteries - you probably have the wrong abstraction

Если у вас был объект ToyDuck, от какого объекта вы должны наследовать, с точки зрения чисто наследования? Должны ли вы наследовать от утки? Нет - скорее всего, вы должны наследовать от Той.

Суть в том, что вы должны использовать правильный метод абстракции - будь то наследование или композиция - для вашего кода.

Для ваших текущих объектов подумайте, есть ли объекты, которые должны быть удалены из дерева наследования и включены просто как свойство, которое вы можете вызывать и вызывать.

7 голосов
/ 14 февраля 2011

Наследование не подходит для повторного использования кода.Наследование для повторного использования кода обычно приводит к:

  1. Классам с унаследованными методами, которые не должны вызываться к ним (нарушая принцип подстановки Лискова), что приводит в замешательство программистов и приводит к ошибкам.
  2. Глубокие иерархии, где требуется непомерное количество времени, чтобы найти нужный метод, когда его можно объявить где-то в дюжине или более классов.

Обычно дерево наследования не должно иметь глубину более двух или трех уровнейи обычно вы должны наследовать только интерфейсы и абстрактные базовые классы.

Однако нет смысла переписывать существующий код только ради него.Однако, когда вам нужно изменить, попробуйте переключиться на композицию, где это возможно.Это, как правило, позволяет вам модифицировать код небольшими кусками, поскольку между классами будет меньше связей.

4 голосов
/ 01 марта 2011

Наследование является основополагающим

без наследования, без ООП.

прототипирование и делегирование могут использоваться для осуществления наследования (как в JavaScript), что хорошо и функционально эквивалентно наследованию

объекты, сообщения и композиция, но никакое наследование не является объектно-ориентированным, а не объектно-ориентированным.VB5, а не Java.Да, это может быть сделано;запланируйте написание большого количества стандартного кода для раскрытия интерфейсов и операций пересылки.

Те, которые настаивают на наследовании, не нужны, или что это "плохо", создают соломенных : это легко представитьсценарии, где наследование используется плохо; это не отражение инструмента, а пользователя инструмента .

4 голосов
/ 14 февраля 2011

Я просто просмотрел текст, но, кажется, он говорит о том, о чем всегда был дизайн ОО: Наследование не подразумевается как инструмент повторного использования кода, а слабая связь хороша. Это было написано десятки раз раньшесм. ссылки в нижней части статьи.Это не означает, что вы должны полностью отказаться от наследования, вы просто должны использовать его осознанно и только тогда, когда это имеет смысл.В статье также говорится об этом.

Что касается печати утки, я нахожу примеры и мысли сомнительными.Например:

function good (foo) {
  if ( !foo.baz || !foo.quux ) {
    throw new TypeError("We need foo to have baz and quux methods.");
  }
  return foo.baz(foo.quux(10));
}

Какой смысл добавлять три новые строки просто для сообщения об ошибке, которая будет автоматически сообщена средой выполнения?

...