Когда вы разрабатываете, когда вы можете определить, есть ли у вас много ненужных классов в вашем приложении? Есть ли определенный лимит на сколько классов вы должны иметь?
Ответ 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 и т.д. Для этого требуется только интерфейс с простым методом записи или использовать его из стандартной библиотеки. В моем случае мне нужно было только вывести его через конкатенацию строк, но для этого мне пришлось открыть псевдо файл в памяти (что обычно не возможно, но язык позволяет это как взломать).
У меня была эта проблема несколько раз, используя случайные библиотеки из всех источников. В некоторых случаях это будет очевидно, когда нужно применять разделение, а иногда и нет. Если вы сомневаетесь, слишком мало по-прежнему бьется слишком много, так как вы обязательно узнаете об этом в конце концов. Я, как правило, замечаю, что если вы добавите что-нибудь, что вы действительно не уверены в себе, вы окажетесь на значительной территории раздувания. Если вы сделаете это, как только вы, вероятно, сделаете это дважды, а затем это станет привычкой.