Подтвердить что ты не робот

Есть ли такая вещь, как слишком много классов?

Когда вы разрабатываете, когда вы можете определить, есть ли у вас много ненужных классов в вашем приложении? Есть ли определенный лимит на сколько классов вы должны иметь?

4b9b3361

Ответ 1

На самом деле нет такого понятия, как "слишком много классов". В чем может быть проблема: "слишком много классов делают одно и то же".

Если вы чувствуете, что у вас слишком много классов в вашей кодовой базе, хороший способ проверить, что бы добавить некоторые новые требования. Все, что заставляет вас внести некоторые изменения в код. (Разумеется, в отдельной ветки контроля источника.) Насколько сложно сделать эти изменения? Требуется ли относительно простое изменение, чтобы вы модифицировали тонны и тонны классов? Если в этом случае есть очень хороший шанс, что у вас слишком много, но проблема не в самом номере.

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

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

В большинстве случаев основной причиной является сопротивление изменениям. Связывание и повторное использование - это то, о чем люди могут спорить подробно, но жесткость программного обеспечения - это то, где аргумент превращается в фактическое усилие (деньги). Проверьте, как сложно внести изменения в код. Затем попробуйте переустановить свои классы/логику таким образом, который, по вашему мнению, будет более восприимчивым к изменениям и повторите проверку. Было ли значительное улучшение?

Ответ 2

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

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

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

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

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

Ответ 3

В проекте, над которым я сейчас работаю, я определенно думаю, что мы используем слишком много классов - или, по крайней мере, слишком много объектов/экземпляров.

Мы построили CMS на основе PHP/MySQL, где каждая запись и поле в базе данных представлены как объект в PHP. Это может привести к десяткам тысяч экземпляров одновременно, и мы постоянно сталкиваемся с проблемами производительности/нехваткой памяти и т.д.

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

Ответ 4

Кент Бек отвечает на ваш вопрос. Джефф Лэнгр в книге "Чистый код" Руководство по гибкому программному мастерству "обсуждает четыре правила проектирования, как указано Кентом Бекем.

(в порядке важности)

  • Запускает все тесты
  • Содержит дублирование
  • Выражает намерение программиста
  • Минимизирует количество классов и методы

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

(заметьте, это мнение Кента Бекса, не так много!)

Ответ 5

Как и многие другие, "это зависит..."

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

Лично я предпочитаю думать в терминах API, построенного на двух уровнях: более низкий уровень, состоящий из общих, независимых частей и высокого уровня, где я использую пару фасадов, директоров и т.д., чтобы представить что-то конкретное и полезное для других кодеров. Это очень похоже на дизайн iOS-библиотек IMHO.

Ответ 6

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

Ответ 7

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

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

Если вы используете Visual Studio 2012, тогда http://msdn.microsoft.com/en-us/library/bb385910.aspx и http://msdn.microsoft.com/en-us/library/dd264939.aspx содержит информацию о том, как работают кодовые метрики и анализ кода.

Это пример отчета из метрики кода в Visual Studio 2012 на основе моего собственного приложения, значения которого объясняются на http://msdn.microsoft.com/en-us/library/bb385914.aspx.

Project: <<Projectname>>
Configuration: Debug
Scope: Project
Assembly: <<Path>>
Maintainability Index: 84
Cyclomatic Complexity: 479
Depth of Inheritance: 8
Class Coupling: 189
Lines of Code: 903

Ответ 8

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

Если для разных слоев существуют разные классы для хранения практически одинаковых данных. Это будет считаться плохим, поскольку классы DTO не должны дублироваться по уровням.

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

Ответ 9

Философские:

Есть такая вещь, как слишком много чего. У вас может быть слишком много и слишком мало занятий. Некоторым нравится притворяться, что больше свободного, потому что они могут использовать такие инструменты, как поиск, как предлог для создания чрезмерно грязного, труднодоступного и большого пространства для поиска. В конечном итоге вы всегда найдете измеримый дефицит.

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

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

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

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

Обнаружение:

Простой способ взглянуть на это, если у вас есть путь A (одиночный node/одна функция/класс/etc), но разбить его на A- > B, вы ничего не получили. Вы просто взяли один лист бумаги, разорвали его на две части, положили в два конверта и отправили в пункт назначения. Если окажется, что на самом деле вам действительно нужен node с более чем одним краем, вы получаете что-то. Это было бы, например, A- > B, A- > C. Вы можете использовать графический анализ, чтобы вынюхать слишком много объектов. Если у вас есть большие длинные связанные списки или многие небольшие связанные списки (или, возможно, даже несколько), то вы, вероятно, можете сказать, что у вас слишком много классов. Не все формы излишеств объектов настолько легко обнаруживаются. С слишком большим количеством обслуживания содержание становится чрезмерно сложным, так как вы оказываете поддержку уровню гибкости и модели, из которых только одна доля вы используете. Это означает, что большая часть вашего кода фактически не соответствует тому, что нужно сделать. Это само по себе затрудняет поддержание, поскольку цель этого кода является субъективной, а не объективной, она также может быть произвольной.

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

Несмотря на то, что он измерим, нет точной меры слишком большого количества классов или идеального знака. Есть только намеки. Большое значение между минимальным количеством классов и максимумом, например, является подсказкой. Что такое большое? Я бы сказал, что 100 раз определенно подозревается, 10 раз довольно подозрительно, в 5 раз немного подозрительно. Это может измениться, хотя на основе нескольких параметров.

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

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

Если вы посмотрите на свои классы, вы можете выбрать некоторые вещи. Какая часть кода OO и сколько FO (ориентированный объект против Ориентация на функциональность)?

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

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

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

Причины:

Это может быть обусловлено рядом вещей от механизмов, которые делают его очень легким для создания и соединения вещей (которые, как правило, ломаются, когда вы абстрагируетесь и делаете то, что динамично поощряет избегать хороших привычек, которые заменяют, но нарушают IDE), Я часто попадал в ловушку этого, пытаясь представить все абсолютно отлично, однако OO на самом деле недостаточно гибко, чтобы это делать, и часто оказывается YAGNI. Общей проблемой является просто отсутствие абстракции, в которой вы обычно используете переменную разворачивание в языковые конструкции верхнего уровня, как упоминалось ранее (что также связано с дизайном, чтобы напрямую разоблачить все в среде IDE). Это может не только превзойти отсутствие динамического кодирования, но и использовать препроцессор или аналогичный. Как это будет выглядеть, в основном это дерево со всеми определенными листьями. Как можно больше с классами вы хотите избежать необходимости определять класс для каждого возможного листа. Знак расширения дерева, сделанный до крайности, может быть там, где у вас есть класс для каждого возможного использования примитива. Это также может быть признаком чего-то более экстремального. Развернутое декартово произведение всех классов. В этом случае вы не просто получаете класс для нога, а класс для CatLeg, DogLeg и т.д., Когда обычно нет реальной дисперсии между ними. Некоторые люди могут сделать это из экстремизма проверки типа, чтобы остановить кого-то, кто помещает DogLeg в CatLeg. Это неприятный и распространенный анти-шаблон.

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

Это очень распространено в таких вещах, как SOLID. Очень важно знать и понимать такие принципы, как SOLID, возможность применять их, но также важно знать, когда их не применять.

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

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

Пример счетчика:

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

Недавно я использовал библиотеку в Интернете со слишком небольшим количеством классов. Он содержал один класс с несколькими обязанностями. Для записи потребуется обработать файл (как примитивный тип), а затем автоматически выводить заголовки HTTP, соответствующие потоку, который он генерирует, на основе методов (таких как addImage, addText и т.д.).

В идеальном мире этот класс не должен был делать предположений о выходе. Использование может потребоваться для вывода в файловую систему, память, поток TCP и т.д. Для этого требуется только интерфейс с простым методом записи или использовать его из стандартной библиотеки. В моем случае мне нужно было только вывести его через конкатенацию строк, но для этого мне пришлось открыть псевдо файл в памяти (что обычно не возможно, но язык позволяет это как взломать).

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