сколько классов в пакете? методы на класс? строк на метод? - PullRequest
28 голосов
/ 23 ноября 2008

Я должен сделать общее примечание к какому-то огромному Java-проекту, для которого у меня мало видимости, и мне было интересно, есть ли какие-нибудь рекомендации для определения:

  • какое количество классов в пакете можно считать правильным, низким или высоким (этот проект имеет 3,89 классов на пакет, что мне кажется слишком маленьким),
  • количество методов в классе? (этот проект имеет 6,54 метода на класс ...
  • количество строк на метод? (в этом проекте около 7 строк на метод (мне кажется, это неплохо, может быть, немного мало))

Должен отметить, что этот вопрос касается только объема. У меня есть куча отчетов от качественных инструментов (checkstyle, jdepend, cpd, pmd, ncss), которые дают мне больше видения избыточности кода, использования классов, ошибок и т. Д.

Ответы [ 6 ]

24 голосов
/ 23 ноября 2008

Стив Макконнелл в своей книге Code Complete рекомендует около 7 методов на класс, и больше строк в методе не может быть просмотрено на одном экране без прокрутки.

Я не уверен насчет классов в пакете.

Я бы настоятельно рекомендовал прочитать Code Complete для получения дополнительной информации по таким темам.

15 голосов
/ 23 ноября 2008

Я думаю, что подобная статистика довольно бесполезна, как знание количества строк в методе показывает, полезно ли это для проекта или нет; я думаю, что вы должны смотреть по-другому:

  1. Ваши пакеты включают в себя как классы?
  2. Ваши занятия работают как сущность самостоятельно?
  3. У методов внутри функции классов правильно и качественно?

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

13 голосов
/ 23 ноября 2008

Роберт К. Мартин, недавно выпустивший книгу «Чистый код», утверждает, что число строк в методе должно быть как можно меньшим. Хорошее эмпирическое правило между 1-7 строками.

В книге «Антология ThoughtWorks», а также в эссе Джеффа Бэя «Этюд по художественной гимнастике», есть и хорошая мысль. Он предлагает 9 довольно жестких ограничений, которые сделают вас лучшим разработчиком ОО в долгосрочной перспективе. Подробнее о них можно прочитать здесь.

Чтобы ответить на ваши конкретные вопросы, это ограничения специально для вас: - не более 10 занятий в упаковке - максимум 50 строк в классе

Эти ограничения могут быть не идеальными для всех ваших реальных проектов, но их использование в небольшом (хобби?) Проекте приведет вас к лучшей практике.

5 голосов
/ 23 ноября 2008

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

Для методов вы можете принять аналогичное представление и стремиться к методам, которые как можно меньше, но не меньше. Подумайте об этом так: если вы можете разделить метод на две или более отдельные части, он явно не такой маленький, как мог бы быть. Небольшие методы легко понять, и, разбив подобный код, вы получите лучший обзор методов высокого уровня и перенесете подробности в методы низкого уровня.

5 голосов
/ 23 ноября 2008

К сожалению, в программном обеспечении нет абсолютного (объективного) понятия качества. Таким образом, нет «правильного» значения для них. Однако вот два (личных) замечания:

3,89 классов / пакет очень низкий. Это означает, что вы будете сражаться через сложное дерево пакетов.

7 строк на метод: действительно звучит хорошо. Однако, если это число было получено в результате преднамеренных усилий по сокращению количества строк методов, вы могли бы в конечном итоге получить одну логическую задачу, распределенную по нескольким частным методам, что затруднит понимание класса ( в определенных случаях). На самом деле в CodeComplete-2 автор цитирует исследование, которое обнаружило, что длина метода гораздо менее важна, чем его цикломатическая сложность и уровень вложенности.

1 голос
/ 23 ноября 2008

(примечание: tl; dr доступно в самом низу для моего реального мнения)

Я не собираюсь цитировать какое-либо громкое имя и говорить, что это правильный ответ, потому что это всегда очень зависит от того, как вы все это делаете. Например, количество методов: Если вы создаете управляющее программное обеспечение для пульта ДУ современного HD LCD телевизора, который имеет около 40-50 кнопок, как вы можете разбить его на классы связно , чтобы у вас было только как, скажем, 7 методов в классе?

Лично мне нравится хранить все методы одного уровня доступа в одном классе, что означает, что некоторые служебные классы могут иметь сотни методов, но, по моему мнению, проще сделать что-то вроде StringUtil.escapeXMLspecialCharacters(someString), чем StringUtil.XML.escapeSpecialCharacters(someString) или * 1009. *. Хотя все эти решения кажутся нормальными, первое процветает (по крайней мере, на мой взгляд, так!), Потому что это простой и очень простой способ получить доступ к этому методу: вам не нужно думать, содержит ли строка, которую вы обрабатываете XML, XHTML, JSON или что-то еще, вы просто выберете один метод из общей группы методов и все.

Продолжая аналогию с предыдущим телевизионным пультом, давайте предположим, что вы все равно делите их на различные классы. Если мы позволим себе иметь в среднем по 7 таких методов на класс и сумеем сгруппировать кнопки на пульте в сенсорные группы, такие как MenuButtons, AdjustmentButtons и NumberSelectorButtons, мы получим около 8 классов. Это на самом деле неплохо, но легко запутывается, особенно если они не разделены на чувственные группы с большой осторожностью. Представьте себе, что вокруг вашего офиса TVRemotes'R'Us Inc. - шум: «Кто сказал, что кнопка включения / выключения - это кнопка управления?» «Кто тот джокер, который поставил громкость +/- на кнопки меню? PRE / CH (кнопка, которая переключается между текущим и предыдущим каналом и / или источником изображения) * Кнопка 1015 * не является цифровой кнопкой!» «Кнопка гида открывает как телепрограмму, так и навигационное меню в зависимости от контекста, что мы будем с этим делать!?»

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

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

А вот и TL; DR :

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

  • Пакет foo содержит интерфейсы и другие общие классы для реализаций.
  • Пакет foo.bar содержит реализацию указанных интерфейсов для функции bar
  • Пакет foo.baz содержит реализацию указанных интерфейсов для функции baz

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

Методы в классе: все, что необходимо, как я объяснил выше. Если ваш класс не может жить без 170 методов, то пусть у них есть. Рефакторинг - это добродетель, а не то, что можно применять постоянно.

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

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