Что делать с исходным файлом C ++ из 11000 строк? - PullRequest
226 голосов
/ 01 сентября 2010

Итак, в нашем проекте есть огромный исходный файл mainmodule.cpp (размером 11000 строк?), И каждый раз, когда мне приходится его трогать, я съеживаюсь.

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

Файл используется и активно изменяется в нескольких (> 10) версиях обслуживания нашего продукта, поэтому его очень трудно реорганизовать. Если бы я «просто» разделил его, скажем для начала, на 3 файла, то объединение изменений из версий обслуживания станет кошмаром. А также, если вы разделите файл с такой длинной и богатой историей, отслеживание и проверка старых изменений в истории SCC внезапно станет намного сложнее.

Файл в основном содержит "основной класс" (основной внутренний диспетчерский состав и координацию) нашей программы, поэтому каждый раз, когда добавляется функция, он также влияет на этот файл и каждый раз, когда он увеличивается. : - (

Что бы вы сделали в этой ситуации? Любые идеи о том, как переместить новые функции в отдельный исходный файл, не испортив рабочий процесс SCC?

(Примечание по инструментам: мы используем C ++ с Visual Studio; мы используем AccuRev как SCC, но я думаю, что тип SCC здесь на самом деле не имеет значения; мы используем Araxis Merge для фактического сравнение и объединение файлов)

Ответы [ 34 ]

2 голосов
/ 05 сентября 2010
  1. Никогда не трогайте этот файл и код снова!
  2. Лечить - это то, с чем ты застрял.Начните писать адаптеры для функциональности, закодированной там.
  3. Пишите новый код в разных единицах и разговаривайте только с адаптерами, в которых заложены функциональные возможности монстра.
  4. ... если только одно из вышеперечисленных невозможно, оставьте работу и получитеновый.
2 голосов
/ 04 сентября 2010

Я нашел это предложение самой интересной частью вашего сообщения:

> Файл используется и активно изменяется в нескольких (> 10) версиях нашего продукта для обслуживания, поэтому его очень трудно реорганизовать

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

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

Я чувствую, что ты уже съеживаешься! Но либо ваш источник управления не работает для вашей ситуации из-за отсутствия функций, либо он используется неправильно.

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

Я был бы немного обеспокоен тем, что у вас так много в вашей функции main ().

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

Я бы также инициализировал объект регистрации приложения в main для глобального использования в программе.

Наконец, в основной я также добавляю код обнаружения утечки в блоки препроцессора, который гарантирует, что он включен только в сборках DEBUG. Это все, что я хотел бы добавить к main (). Main () должен быть коротким!

Вы говорите, что

> Файл в основном содержит "основной класс" (диспетчеризация и координация основной внутренней работы) нашей программы

Похоже, эти две задачи можно разделить на два отдельных объекта - координатор и диспетчер работ.

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

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

2 голосов
/ 03 сентября 2010

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

2 голосов
/ 02 сентября 2010

Другая книга, которую вы можете найти интересной / полезной, - Рефакторинг .

2 голосов
/ 02 сентября 2010

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

2 голосов
/ 01 сентября 2010

Мои 0,05 евроцента:

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

При разбиении на подсистемы анализируйте места, которые наиболее изменились, и отделяйте их от неизменных частей.Это должно показать вам проблемные места.Разделите наиболее изменяющиеся части на их собственные модули (например, dll) таким образом, чтобы можно было сохранить API модуля без изменений, и вам не нужно все время ломать BC.Таким образом, при необходимости можно развернуть разные версии модуля для разных веток обслуживания, не меняя ядро.

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

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

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

Вот как я бы начал решать проблему, по крайней мере.

2 голосов
/ 01 сентября 2010

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

Если вы нашли работоспособное решение, выполните рефакторинг приложения соответствующим образом.

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

1 голос
/ 03 сентября 2010

Просто угадайте, если этот код обслуживает 10 клиентов и содержит варианты кода, у вас может быть много клонов кода с вариантами для конкретных клиентов

Я бы очень хотел запустить детектор клонов на ваших 11 000файл строки.(На самом деле, если вы отправите его мне, я сделаю это с помощью моего детектора клонов, поддерживающего C ++ [см. Биографию] и вышлю вам ответ).

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

1 голос
/ 02 сентября 2010

Это сложный и интересный рефакторинг.

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

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

тогда вы можете искать вызывающих и заставлять их вызывать ваш компонент.Это легкая часть.

1 голос
/ 01 сентября 2010

Я думаю, что я бы сделал в этой ситуации немного пули и:

  1. Выясните, как я хотел разделить файл (на основе текущей версии разработки)
  2. Установить административную блокировку для файла («Никто не трогает mainmodule.cpp после 5 вечера пятницы !!!»
  3. Проведите долгие выходные, применяя это изменение к> 10 версиям обслуживания (от самой старой до самой новой), вплоть до текущей версии.
  4. Удалить mainmodule.cpp из всех поддерживаемых версий программного обеспечения. Это новая эра - больше нет mainmodule.cpp.
  5. Убедите руководство, что не следует поддерживать более одной версии программного обеспечения для обслуживания (по крайней мере, без большого контракта на поддержку $$$). Если у каждого из ваших клиентов есть своя уникальная версия .... yeeeeeshhhh. Я бы добавил директивы компилятора, а не пытался поддерживать более 10 вилок.

Отслеживание старых изменений в файле просто решается вашим первым комментарием о регистрации, который говорит что-то вроде «split from mainmodule.cpp». Если вам нужно вернуться к чему-то недавнему, большинство людей запомнят изменения, если через 2 года в комментарии будет указано, где их искать. Конечно, насколько ценным будет вернуться назад на 2 года, чтобы посмотреть, кто изменил код и почему?

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