Несколько дней назад я разговаривал с кандидатом наук по программной инженерии, и в какой-то момент она сказала мне:
Держите ваши классы и методы как можно меньше
И мне интересно, всегда ли это хорошая практика.
Я имею в виду, например, стоит ли иметь класс с двумя аттибутами? Например, в некоторых методах мне нужны пары целых чисел для работы. Должен ли я написать класс "PairOfIntgers"?
Может ли этот способ мышления «разбить» код на слишком много частей?
code-quality
coding-style
Флоренс Целай
источник
источник
"As small as possible, but no smaller."
Ответы:
В этом совете есть доля правды, но ИМХО он не очень хорошо выражен, поэтому его легко неправильно понять и / или привести к глупой крайности. В любом случае, это должно быть практическим правилом, а не жестким законом. И вы всегда должны включать в такие правила пункт «в разумных пределах» или «но не забывайте использовать свой здравый смысл» :-)
Зерно истины заключается в том, что на практике классы и методы всегда имеют тенденцию расти от природы, а не уменьшаться . Исправление ошибки здесь, небольшое расширение функций там, обработка особого случая там ... и вуаля, ваш когда-то аккуратный и маленький класс начинает раздуваться. Со временем ваш код почти неизбежно станет чудовищным беспорядком спагетти - если вы не будете активно бороться с этой тенденцией посредством рефакторинга . Рефакторинг почти всегда дает множество небольших классов / методов из нескольких больших. Но, конечно, есть разумный предел миниатюризации. Смысл рефакторинга состоит не в том, чтобы иметь меньшие классы и методы как таковые, а в том, чтобы сделать ваш код чище, проще для понимания и сопровождения., В определенный момент уменьшение ваших методов / классов начинает снижать читабельность, а не увеличивать ее. Стремитесь к этому оптимуму. Это размытая и движущаяся область цели, поэтому вам не нужно наносить удары по ней. Просто улучшайте код всякий раз, когда вы замечаете какую-то проблему с ним .
источник
Более важная проблема, которую стоит подчеркнуть, это создание хороших абстракций . Небольшие классы , которые слабо связаны и имеют высокую степень сцепления, являются продуктом хороших абстракций .
Иногда имеет смысл инкапсулировать два целых числа в классе. Особенно, если вы хотите, чтобы к этому классу были присоединены методы, которые также инкапсулируют, как можно манипулировать этими атрибутами, и гарантируют, что вы защищаете их от других частей программы, изменяя их.
Другим положительным моментом для создания класса в этом случае является то, что класс может развиваться намного лучше / лучше, чем, скажем, структура данных более низкого уровня, такая как Map или List.
В-третьих, хорошая абстракция может значительно улучшить читаемость. Классы, которые придерживаются SRP, обычно намного легче понять человеку, чем классы, которые этого не делают.
И просто в качестве заключительного замечания ... независимо от того, насколько вы хороши из студента ... чтобы понять ООП и хорошие абстракции и когда их использовать, вам нужен опыт. Вам нужно написать плохой код и пройти через боль, чтобы поддерживать его. Вы должны видеть, как другие пишут хороший код, чтобы укрепить свои знания о том, что является «хорошим» и что будет проблемой в будущем ... Так что не мучайте себя, если вы просто не получите его сразу.
источник
Анти-паттерн «Объект Бога» - это то, на что она, вероятно, ссылалась. Я склонен думать, что если в описании моего класса есть «и», у меня должно быть два класса. Если у меня есть более десяти строк кода в методе / функции, я должен разбить их. Как пиратский код, это скорее руководство, чем правила.
источник
В объектно-ориентированном программировании принцип единой ответственности гласит, что каждый объект должен нести одну ответственность, и эта ответственность должна быть полностью инкапсулирована классом. Обычно вы делаете больше чем одно, если ваш класс становится слишком большим. В вашем случае класс - это просто класс данных, который содержит данные, что в целом нормально. Вы не должны называть класс 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
источник
Сделайте вещи максимально простыми, но не проще. Это правило, которое я стараюсь соблюдать. Иногда для класса имеет смысл делать то, что строго говоря, означает больше, чем одно, если эти вещи связаны какой-то общей темой . Посмотрите на .NET; Есть тонны классов, которые реализуют большое количество интерфейсов, каждый со своим собственным списком необходимых членов. Метод может в конечном итоге стать несколько длинным, если он делает что-то сложное с рядом промежуточных шагов, которые все взаимосвязаны и, таким образом, не очень хорошо поддаются дальнейшему рефакторингу. (Рефакторинг для того, чтобы методы были короткими, в конечном итоге должен быть связан с удобочитаемостью и удобством обслуживания; если длинный метод более читабелен и / или удобен в обслуживании, чем короткий, при прочих равных условиях я буду использовать длинный в любой день.)
«Делать классы и методы как можно меньше», на мой взгляд, ошибочно. Как указывает @c_maker, реальная задача - обеспечить хорошие абстракции. Ваш пример объединения двух чисел великолепен, например, если вы работаете над реализацией арифметики комплексных чисел или если в системе Unix вам нужно обратиться к контексту пользователя / группы. Не имеет смысла, если числа представляют, скажем, идентификатор счета-фактуры и идентификатор продукта, который будет добавлен в этот счет-фактуру.
источник
Это хороший совет, но он должен быть реализован несколько разумно. Определенно не следуйте этому вслепую.
Когда я смотрю на свой код, я знаю, является ли метод слишком большим. Если он делает слишком много, и его будет слишком сложно читать, то это время рефакторинга.
Вот хороший пример: у вас есть цикл, и у вас может быть 60 строк кода в этом методе. В этом случае, вероятно, пришло время провести рефакторинг, потому что вы, вероятно, делаете слишком много в этом методе.
Но это не жесткое и быстрое правило. Это только то, чему вы научитесь на практике. И другие разработчики, с которыми вы работаете, не всегда соглашаются и могут вызывать вас в обзоре кода или как угодно.
источник
Дядя Боб говорит, что вы должны реорганизовать / разделить / извлечь ваши методы, пока их невозможно уменьшить . Обычно это заканчивается наличием нескольких методов по 3 или 4 строки в каждом. Когда вы получаете слишком много методов, вы должны создавать больше классов.
Если вы попытаетесь следовать SRP и одному уровню абстракции для каждого метода, эти правила вам пригодятся. По крайней мере, они служат мне хорошо. Стремление к «как можно меньшему» дает мне разумные маленькие методы, поскольку я обычно не достигаю цели.
И всегда легче понять меньшие классы. Продолжайте читать «Чистый код»
источник