наследование против состава для тестируемости - PullRequest
25 голосов
/ 17 апреля 2009

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

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

Ответы [ 5 ]

30 голосов
/ 17 апреля 2009

Я считаю, что чем больше вы начинаете разрабатывать с использованием шаблонов проектирования, тем чаще и чаще вы будете находить, где композиция будет предпочтительнее наследования. Я действительно верю в книгу Head First: Design Patterns , что " композиция Favor Over Inheritance " является одним из основных принципов проектирования.

Ваш пример возможности макетировать части композиции для тестирования, возможно, является одним из лучших возможных примеров.

Редактировать : Хотя основной принцип в шаблонах проектирования - отдавать предпочтение композиции, а не наследованию, это не означает, что не существует шаблонов проектирования, которые используют наследование там, где это необходимо. Другим базовым примером является шаблон декоратора, где вы кодируете в направлении абстрактного суперкласса (хотя это для сопоставления типов, а не для реализации отношения «есть»).

10 голосов
/ 17 апреля 2009

Это не та или иная ситуация. Они не конкуренты.

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

Наследование может быть использовано неправильно. Некоторые проекты выглядят как ситуации «есть», но на самом деле это не так - они более тонкие. Иногда это действительно «ведет себя как», когда вам нужна какая-то композиция (например, Strategy ) для отделения поведения от других атрибутов.

8 голосов
/ 17 апреля 2009

The Gang of Four Design Patterns * Книга 1002 *, в основном, посвящена тому, почему предпочтение композиции, а не наследованию, и предлагает множество способов сделать это. Несколько причин:

  1. классов увеличивает сложность базы кода

  2. Во многих новых языках наследование ограничено одним классом, в то время как вы можете составлять столько, сколько хотите
  3. Базовые классы не могут быть изменены во время выполнения (по сути, проблема, с которой вы сталкиваетесь).
5 голосов
/ 17 апреля 2009

Я думаю, что главная причина, по которой состав проще тестировать, заключается в том, что наследование (реализация) имеет тенденцию создавать очень связанные классы, которые являются более хрупкими (Fragile Base Class) и которые сложнее тестировать изолированно.

Наследование определенно имеет свое применение, но я все чаще и чаще предпочитаю композицию наследованию.

3 голосов
/ 17 апреля 2009

"Композиция объекта Favour по наследованию класса" фактически из книги GoF. Этот разговор с Эрихом Гаммой описывает эту идею из книги.

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

...