Сколько типов слишком много для объекта? - PullRequest
1 голос
/ 28 июня 2011

Я понимаю, что этот вопрос не полностью прорезан, но в целом, как вы узнаете, когда объект имеет слишком много типов?

В настоящее время я поддерживаю проект, в котором я не знаком с базовым уровнем, но в основном мне поручено исправлять ошибки, чтобы уменьшить количество элементов в нашей базе данных SPR. Я продолжаю сталкиваться с классами, которые расширяют множество различных интерфейсов, включая один такой класс, который расширяет в общей сложности двенадцать. Многие другие расширяют 7 или 8.

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

Ответы [ 7 ]

1 голос
/ 28 июня 2011

Класс может расширять 12 интерфейсов, но если эти 12 контрактов представляют пересечение поведения, так что объект все еще имеет только одну ответственность, то есть A-OK.Снова и снова в крупных корпоративных проектах наиболее сложными для обслуживания являются классы, которые пытаются сделать слишком много разных вещей.Вот пример:

Приложение, которое выполняет маршрутизацию и рекомендации для лиц, принимающих первые ответные меры (полиция, пожарная охрана и т. Д.), Имеет класс Mapping, который делает:

  • геокодирование и обратное геокодирование (поворотlat & long в адрес и наоборот)
  • отображение изображения карты на экране, с трафиком и маршрутизацией «бликов»
  • поиск маршрутов между различными местоположениями
  • анализсхемы трафика, предоставляемые сторонними источниками данных

Первоначальный разработчик системы, должно быть, подумал: «Ну, это все задачи, связанные с картой и местоположением, так что да, это должен быть один класс».К сожалению, это сделало невозможным дальнейшее изменение одного из этих элементов функциональности, поскольку все было тесно связано.

Найдите швы в функциональности, предоставляемой различными компонентами вашего приложения.Разделите эти швы на сплоченные контракты (интерфейсы) между компонентами, где каждое устройство способно предоставить ценную «услугу» (не в смысле веб-сервиса) своим потребителям.Чтобы вернуться к моему предыдущему примеру, мы в итоге разбили класс Mapping (Project Yoko) на:

  • Геокодер
  • MapRenderer
  • RouteRenderer
  • RouteBuilder
  • TrafficRenderer (унаследованный от RouteRenderer)
  • TrafficDatasource

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

1 голос
/ 28 июня 2011

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

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

Также я вижу в этом признак того, что дизайнер хорошо мыслит.

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

1 голос
/ 28 июня 2011

Чтобы доказать, что запах кода должен отвечать (правильные ответы в parethesis):

  • Используется ли данный объект для выполнения двенадцати различных целей?ДА
  • Эти цели слишком тесно связаны?НЕТ
  • Есть ли уколы для этого объекта, которые никогда не используются?НЕТ
  • Существуют ли цели для этого объекта, которые используются редко, что может быть частью более общей цели?НЕТ
  • Существуют ли цели, которые вообще не цели, а просто маркеры, используемые во время выполнения?НЕТ

Возможно, есть еще вопросы, на которые можно ответить, не стесняйтесь добавлять в комментарии.

1 голос
/ 28 июня 2011

Как вы сказали, это не просто, но на это определенно стоит обратить внимание.Я думаю, что лучший способ ответить на ваш вопрос с помощью другого вопроса: «У каждого класса есть четко определенная цель и набор обязанностей?»Если ответ «Да», то, возможно, дизайн в порядке или в худшем случае имеет слишком гранулированные интерфейсы.

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

0 голосов
/ 13 сентября 2013

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

0 голосов
/ 28 июня 2011

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

0 голосов
/ 28 июня 2011

Взгляните на некоторые классы в пространстве имен .Net System.Collections.Generic - многие из них поддерживают более 7 интерфейсов. Это не то, о чем нужно беспокоиться (с точки зрения дизайна). Класс должен реализовывать все интерфейсы, которые он должен был реализовать.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...