Руководства по кодированию:Как вы разделяете большие исходные файлы?

StackOverflow https://stackoverflow.com/questions/608530

Вопрос

Проект, над которым я работаю, только что достиг 4200 строк в основном файле C#, из-за чего IntelliSense требуется несколько секунд (иногда до 6 или около того) для ответа, в течение которых Visual Studio блокируется.Мне интересно, как все остальные разделяют свои файлы и есть ли консенсус.

Я пытался поискать какие-нибудь руководства и нашел Руководство Google по C++, но я ничего не увидел о семантике, такой как размеры функций и размеры файлов;возможно оно и есть - я давно на него не заглядывал.

Так как же разделить файлы?Группируете ли вы свои методы по функциям, которые они выполняют?По типам (обработчики событий, частные/публичные)?И до какого предела размера вы разделяете функции?

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

Это было полезно?

Решение

Я думаю, что ваша проблема суммируется с термином, который вы используете:«Основной файл C#».

Если вы не имеете в виду main (как в методе main()), для этой концепции нет места.

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

Обычно мои файлы представляют собой просто сопоставления классов один к одному.

Иногда очень связанные классы находятся в одном файле.

Если ваш файл слишком велик, это означает, что ваш класс слишком большой и слишком общий.

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

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

РЕДАКТИРОВАТЬ:

Чтобы ответить на ваш вопрос об ограничении размера в отношении функций, для меня речь идет не столько о размере (хотя это хороший индикатор проблемы), сколько о том, чтобы делать только одну вещь и сохранять каждую из них ПРОСТОЙ.

Другие советы

В классической книге "Структурированное программирование«Дийкстра однажды написал раздел, озаглавленный:«О нашей неспособности сделать много». Его точка была проста.Люди не очень умны.Мы не можем жонглировать в уме более чем несколькими понятиями одновременно.

Очень важно, чтобы ваши классы и методы были небольшими.Когда метод превышает дюжину строк или около того, его следует разбить на части.Когда класс превышает пару сотен строк, его следует разбить на части.Это единственный способ сохранить код хорошо организованным и управляемым.Я занимаюсь программированием уже почти 40 лет, и с каждым годом я понимаю, насколько важно слово «маленький» при написании программного обеспечения.

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

Разделяйте типы там, где это естественно, но остерегайтесь типов, которые делают слишком много.Примерно при 500 строках (Java или C#) я начинаю беспокоиться.Примерно на 1000 строках я начинаю внимательно думать, следует ли разделить шрифт...но иногда этого просто не может/не должно быть.

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

Иногда имеет смысл иметь один тип много методов - таких как System.Linq.Enumerable но в таких случаях могут помочь частичные классы, если разбить тип на логические группы (в случае Enumerable, группировка по операциям агрегирования/множества/фильтрации и т. д. могла бы показаться естественной).Хотя такие случаи, по моему опыту, редки.

Книга Мартина Фаулера Рефакторинг Я думаю, это дает вам хорошую отправную точку для этого.Он инструктирует, как определить «запахи кода» и как рефактор вашего кода, чтобы исправить эти «запахи». Естественный результат (хотя это не основная цель) заключается в том, что вы в конечном итоге получаете меньшие более масштабные классы.

РЕДАКТИРОВАТЬ

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

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

Не кодируйте процедурно, и вы не получите 4200 строк в одном файле.

В C# рекомендуется придерживаться некоторых ТВЕРДЫЙ принципы объектно-ориентированного проектирования.У каждого класса должна быть одна и только одна причина для изменений.Основной метод должен просто запускать отправную точку приложения (и настраивать контейнер внедрения зависимостей, если вы используете что-то вроде StructureMap).

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

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

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

Я прекращаю занятия, когда чувствую, что они делают больше, чем одно дело, например смешивают презентацию и логику.Большой класс представляет собой меньшую проблему, чем большой метод, если класс делает одну вещь.

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

Вам следует прочитать о стиле C# и рефакторинге, чтобы действительно понять проблемы, которые вы решаете.

Рефакторинг — отличная книга, в которой есть советы по переписыванию кода, чтобы сохранить поведение, но код стал более понятным и с ним было легче работать.

Элементы стиля C# — хорошее руководство по стилю C# для «мертвого дерева», и это Сообщение блога имеет ряд ссылок на хорошие онлайн-руководства по стилю.

Наконец, рассмотрите возможность использования FXCop и СтильКоп.Они не помогут ответить на заданные вами вопросы, но помогут выявить другие стилистические проблемы вашего кода.Раз уж вы опустили палец ноги в воду, то можете и прыгнуть.

Это много, но развитие вкуса, стиля и ясности — главное отличие хороших разработчиков от плохих.

Каждый класс должен сделать одно маленькое дело и сделать его хорошо.Является ли ваш класс формой?Тогда в нем не должно быть НИКАКОЙ бизнес-логики.

Представляет ли он единую концепцию, например, пользователя или состояние?Тогда у него не должно быть никаких рисунков, загрузки/сохранения и т. д.

Каждый программист проходит этапы и уровни.Вы осознаете проблему на своем текущем уровне и готовы перейти к следующему.

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

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

Дай мне найти хороший пост...Просмотрите их для начала:

как-я-разрушить-мои-привычки-процедурного-кодирования

Есть ли какие-нибудь правила для ОП?

объектно-ориентированные-лучшие-практики-наследование-v-композиции-v-интерфейсы

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

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

Удачи.

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

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

  • Используете ли вы какие-либо разделы #region?Логические группировки связанных методов в #region часто позволяют разделить их на отдельные классы.

  • Является ли класс формой?Рассмотрите возможность использования пользовательских элементов управления для элементов управления формой или групп элементов управления формой.

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

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

Есть очень веские причины разбивать файлы классов на более мелкие файлы (и не менее веские причины перемещать файлы в разные проекты/сборки).

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

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

  • Общие принципы ООП
  • Доменно-ориентированный дизайн
  • Модульное тестирование
  • МОК Контейнеры

Удачи в поисках.

Используйте частичные классы.По сути, вы можете разбить один класс на несколько файлов.

Возможно, ОП сможет ответить:ваш проект использует объектно-ориентированное программирование?Тот факт, что вы используете слово «файл», говорит о том, что это не так.

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

Синтаксический анализатор Intellisense в Visual Studio 2008 кажется значительно быстрее, чем в 2005 году (я знаю, что они специально проделали большую работу в этой области), поэтому, хотя вам определенно следует в какой-то момент рассмотреть возможность разделения файла, как уже упоминали другие, Visual Studio 2008 может решить вашу непосредственную проблему с производительностью.Я использовал его, чтобы без особых проблем открыть файл Linq to SQL длиной более 100 тыс. строк.

Разделите код так, чтобы каждый класс/файл/функция/и т. д.делает только одну вещь™. Принцип единой ответственности — хорошее руководство для разделения функциональности на классы.

Сейчас самые большие классы, которые я пишу, имеют длину около 200 строк, а длина методов в основном составляет 1-10 строк.

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

Я использую соглашение о наличии ClassName_RegionName.cs.Например, если я хочу выделить класс, который управляет схемой для подключения к базе данных, и я назвал класс DatabaseConnection, я бы создал файл с именем DatabaseConnection.cs для основного класса, а затем DatabaseConnection_Schema.cs для функциональности схемы.

Некоторые классы просто должны быть большими.Это неплохой дизайн;они просто сложны в реализации.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top