Существуют ли какие-либо инструменты статического анализа, которые будут сообщать, насколько тщательно соблюдаются принципы SOLID? - PullRequest
5 голосов
/ 26 октября 2009

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

Недостатком их является то, что им иногда требуется глубокий анализ вашего исходного кода для их применения. Я, как и большинство программистов, постоянно в поиске более эффективных способов ведения дел, поэтому мне любопытно, слышал ли кто-нибудь об инструменте анализа, который пытается протестировать применение принципов SOLID (или его отсутствие).

SRP Единственная ответственность Принцип

У класса должна быть только одна причина менять.

OCP Открыто-Закрыто Принцип

Программные объекты (классы, модули, функции и т. д.) должны быть открыты для расширение, но закрыто для модификация.

LSP Лисков Принцип замещения

Подтипы должны быть заменяемыми для их базовые типы.

ISP Интерфейс Принцип сегрегации

Клиентов не следует заставлять зависеть на методы, которые они не используют. Интерфейсы принадлежат клиентам, а не Иерархии.

DIP Принцип обращения зависимостей

Абстракции не должны зависеть от подробности. Детали должны зависеть от абстракции.

- Из Agile принципов, шаблонов и практик

Ответы [ 2 ]

7 голосов
/ 27 октября 2009

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

Тем не менее, вы можете иметь инструменты, которые помогут вам определить вероятность нарушения. Например, вы можете использовать метрики кода, такие как количество методов в классе, количество членов в классе, чтобы определить, является ли класс слишком большим и, следовательно, может нарушать SRP.

Исключением может быть принцип подстановки Лискова. ЕСЛИ вы определяете контракты для всех методов (предусловия, постусловия, инварианты), то можете проверить, что метод, переопределяющий метод суперкласса, не усиливает предусловие, не ослабляет постусловие и не уважает инварианты метода суперкласса. Я думаю, что инструмент ESC / Java выполняет эти проверки. Чтение страницы Википедии о LSP необходимо выполнить дополнительные проверки.

3 голосов
/ 30 октября 2009

Мой ответ касается конкретного продукта .NET, заранее извиняюсь, и, возможно, кто-то может предложить его аналоги, не относящиеся к .NET.

Я бы попробовал NDepend и посмотрел бы, может ли это привести меня к нарушениям SRP и ISP, используя такие метрики, как:

  • количество методов для типов типов с
  • аномально большое количество методов
  • афферентная / эфферентная связь на уровне сборки и типа
  • другие метрики, полный список метрик здесь

Нарушения DIP и LSP отследить может быть сложнее, поскольку они связаны с намерениями программиста. Инструмент анализа может идентифицировать отношения между типами, но как он может отличить ситуацию, когда один класс действительно расширяет другой от неправильного определения Square из Rectangle? Или, что в правильно разработанной программе A должно зависеть от B, а не наоборот?

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

Однако, если мы считаем, что следование SOLID приводит к более удобному для обслуживания продукту (доказательство этого утверждения не является предметом этого вопроса), тогда диаграмма абстрактности-нестабильности NDepend должна дать хорошую совокупную меру насколько хорошо принципы были соблюдены для каждого программного модуля. Если бы они были, модуль должен был избегать нижнего левого угла графика, получившего название «Зона боли». В этой зоне модуль стабилен (не в хорошем смысле - от него зависит слишком много других, поэтому его сложно изменить), но недостаточно абстрактен.

...