Держите мои классы и методы как можно меньше?

20

Несколько дней назад я разговаривал с кандидатом наук по программной инженерии, и в какой-то момент она сказала мне:

Держите ваши классы и методы как можно меньше

И мне интересно, всегда ли это хорошая практика.

Я имею в виду, например, стоит ли иметь класс с двумя аттибутами? Например, в некоторых методах мне нужны пары целых чисел для работы. Должен ли я написать класс "PairOfIntgers"?

Может ли этот способ мышления «разбить» код на слишком много частей?

Флоренс Целай
источник
10
Это должно быть"As small as possible, but no smaller."
StuperUser
«Я имею в виду, например, стоит ли иметь класс с двумя аттибутами?» - Это может быть, поиск "Примитивная одержимость" (например, jamesshore.com/Blog/PrimitiveObsession.html )
Торстен
Я думаю, что источником путаницы является слово «возможно». Принцип становится нелепым, если «возможный» относится только к коду, потому что наименьший возможный класс, который делает что-либо полезное, имеет только один метод (а в некоторых случаях ноль). Кандидат, скорее всего, хотел принять во внимание сплоченность и сцепление.
Кельвин

Ответы:

23

В этом совете есть доля правды, но ИМХО он не очень хорошо выражен, поэтому его легко неправильно понять и / или привести к глупой крайности. В любом случае, это должно быть практическим правилом, а не жестким законом. И вы всегда должны включать в такие правила пункт «в разумных пределах» или «но не забывайте использовать свой здравый смысл» :-)

Зерно истины заключается в том, что на практике классы и методы всегда имеют тенденцию расти от природы, а не уменьшаться . Исправление ошибки здесь, небольшое расширение функций там, обработка особого случая там ... и вуаля, ваш когда-то аккуратный и маленький класс начинает раздуваться. Со временем ваш код почти неизбежно станет чудовищным беспорядком спагетти - если вы не будете активно бороться с этой тенденцией посредством рефакторинга . Рефакторинг почти всегда дает множество небольших классов / методов из нескольких больших. Но, конечно, есть разумный предел миниатюризации. Смысл рефакторинга состоит не в том, чтобы иметь меньшие классы и методы как таковые, а в том, чтобы сделать ваш код чище, проще для понимания и сопровождения., В определенный момент уменьшение ваших методов / классов начинает снижать читабельность, а не увеличивать ее. Стремитесь к этому оптимуму. Это размытая и движущаяся область цели, поэтому вам не нужно наносить удары по ней. Просто улучшайте код всякий раз, когда вы замечаете какую-то проблему с ним .

Петер Тёрёк
источник
1
безусловно, правило не следовать слепо, слишком много маленьких классов намного хуже, чем несколько больших классов в большинстве случаев.
Ryathal
4
Мое личное правило таково: если вы не видите сразу всю реализацию метода на экране, сделайте рефакторинг.
Дэн Рэй
6
@DanRay, да, у меня было то же правило, пока я не прочитал Чистый код . Это был шок, но постепенно мой оптимум опустился примерно до 10 строк.
Петер Тёрёк
2
ИМО Чистый код ужасен в своей крайности по отношению к маленьким методам. Проблема в том, что когда методы станут меньше, их станет больше. Конечно, слишком длинные методы слишком длинные, но Боб Мартин, похоже, предпочитает 10 однострочных методов над 1-строковым (таким образом, фактически тот же код занимает примерно в 5 раз больше места на экране). Возможно, это должно быть своего рода образовательный трюк, я не могу поверить, что кто-то на самом деле думает, что код в этой книге хорош.
Joonas Pulakka
5
@JoonasPulakka - Скажем так, я никогда не читал метод и подумал: «Хотел бы я, чтобы этот метод делал больше». Сокращая методы, вы можете написать очень описательные имена методов, которые часто могут устранить необходимость полного прочтения тела метода. Я нашел совет в « Чистом коде» очень разумным. Мы просто должны согласиться не согласиться. :)
Дэвид Харкнесс
9

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

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

Другим положительным моментом для создания класса в этом случае является то, что класс может развиваться намного лучше / лучше, чем, скажем, структура данных более низкого уровня, такая как Map или List.

В-третьих, хорошая абстракция может значительно улучшить читаемость. Классы, которые придерживаются SRP, обычно намного легче понять человеку, чем классы, которые этого не делают.

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

c_maker
источник
2

Анти-паттерн «Объект Бога» - это то, на что она, вероятно, ссылалась. Я склонен думать, что если в описании моего класса есть «и», у меня должно быть два класса. Если у меня есть более десяти строк кода в методе / функции, я должен разбить их. Как пиратский код, это скорее руководство, чем правила.

Сардатрион - Восстановить Монику
источник
2

В объектно-ориентированном программировании принцип единой ответственности гласит, что каждый объект должен нести одну ответственность, и эта ответственность должна быть полностью инкапсулирована классом. Обычно вы делаете больше чем одно, если ваш класс становится слишком большим. В вашем случае класс - это просто класс данных, который содержит данные, что в целом нормально. Вы не должны называть класс PairOfInteger. Что описывают целые числа? В зависимости от вашего сценария также может быть достаточно Tuple (как в C #). И вы можете подумать о стойке вместо класса.

Попробуй держать тебя в классах маленьким. И методов еще меньше. Может быть, 10 строк?!? В настоящее время я пытаюсь использовать потоковый дизайн и компоненты, основанные на событиях, которые, кажется, помогают держать классы маленькими. Сначала я волновался, чтобы попасть на многие занятия, но это действительно работает !!! http://geekswithblogs.net/theArchitectsNapkin/archive/2011/03/19/flow-design-cheat-sheet-ndash-part-i-notation.aspx http://geekswithblogs.net/theArchitectsNapkin/archive/2011/03 /20/flow-design-cheat-sheet-ndash-part-ii-translation.aspx

KCT
источник
2

Сделайте вещи максимально простыми, но не проще. Это правило, которое я стараюсь соблюдать. Иногда для класса имеет смысл делать то, что строго говоря, означает больше, чем одно, если эти вещи связаны какой-то общей темой . Посмотрите на .NET; Есть тонны классов, которые реализуют большое количество интерфейсов, каждый со своим собственным списком необходимых членов. Метод может в конечном итоге стать несколько длинным, если он делает что-то сложное с рядом промежуточных шагов, которые все взаимосвязаны и, таким образом, не очень хорошо поддаются дальнейшему рефакторингу. (Рефакторинг для того, чтобы методы были короткими, в конечном итоге должен быть связан с удобочитаемостью и удобством обслуживания; если длинный метод более читабелен и / или удобен в обслуживании, чем короткий, при прочих равных условиях я буду использовать длинный в любой день.)

«Делать классы и методы как можно меньше», на мой взгляд, ошибочно. Как указывает @c_maker, реальная задача - обеспечить хорошие абстракции. Ваш пример объединения двух чисел великолепен, например, если вы работаете над реализацией арифметики комплексных чисел или если в системе Unix вам нужно обратиться к контексту пользователя / группы. Не имеет смысла, если числа представляют, скажем, идентификатор счета-фактуры и идентификатор продукта, который будет добавлен в этот счет-фактуру.

CVn
источник
0

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

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

Вот хороший пример: у вас есть цикл, и у вас может быть 60 строк кода в этом методе. В этом случае, вероятно, пришло время провести рефакторинг, потому что вы, вероятно, делаете слишком много в этом методе.

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

Алан Делимон
источник
Никогда не уменьшайте методы, а следуйте SRP, и он автоматически выполнит свою работу.
Винай Праджапати
0

Дядя Боб говорит, что вы должны реорганизовать / разделить / извлечь ваши методы, пока их невозможно уменьшить . Обычно это заканчивается наличием нескольких методов по 3 или 4 строки в каждом. Когда вы получаете слишком много методов, вы должны создавать больше классов.

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

И всегда легче понять меньшие классы. Продолжайте читать «Чистый код»

Питер Кофлер
источник