Как принципиально перестроить систему, сохранив при этом функциональное поведение?
Я унаследовал приложение ASP.NET, которое является архитектурным бедствием, однако оно работает и находится в рабочем режиме. Чтобы улучшить приложение в будущем, мне нужно полностью перестроить его, но мне нужно сохранить существующую функциональность внешнего интерфейса - изменения, о которых меня просят, - это скорее внутренняя интеграция, чем интерфейсный функционал или взаимодействие с пользователем.,
Основная проблема заключается в том, что основная часть бизнес-логики находится в хранимых процессах (а остальная часть находится в файлах кода за интерфейсом пользователя), и не существует модели бизнес-домена, о которой можно было бы говорить. Мне нужно преобразовать логику из базы данных (и вниз из пользовательского интерфейса) в код, но поведение приложения фундаментально связано с этими хранимыми процессами. Итак, вопрос в том, как вы идете к полной реорганизации такого рода?
Я понимаю рефакторинг небольшими шагами, я прочитал Фаулера и т. Д. Я действительно ищу практические советы от людей, которые прошли через аналогичный процесс.
Спасибо!
Править Я должен был сказать, в идеале я хочу итеративно перестроить, в течение цикла многократного выпуска.
4 ответа
ИМХО, самое важное, что нужно сделать - это разработать множество хороших тестов, которые охватывали бы всю функциональность, которую вы хотите сохранить.
Я знаю, что написание тестов чрезвычайно сложно в грязной кодовой базе, но все еще возможно с помощью некоторых методов взлома зависимостей. Я бы порекомендовал "Эффективно работать с унаследованным кодом", поскольку это все о практической стороне рефакторинга.
Это больно, но первый большой вопрос: вам действительно нужно сделать эту реархитектуру? Если дизайн базы данных более или менее нормален, можете ли вы вместо этого спроектировать новый материал и оставить старый в покое? Каждый рефлекс жаждет навести порядок, но с точки зрения бизнес-пользователя, какой уровень инвестиций требуется и каков окупаемость?
Вы уже определили итеративное изменение как подход. Для того, чтобы это работало, это означает, что в системе есть некоторый уровень детализации, который позволяет вам изменять некоторые части, не затрагивая другие. Предположительно, ваша идея заключается в том, чтобы придать какую-то новую ценность для бизнеса и одновременно очистить некоторую часть приложения - эффективно амортизировать стоимость изменений по многим ценным результатам, "налог на сбор мусора" при доставке новых материалов. Это "налог" приемлем?
Поэтому я думаю, что предположение о гранулярности нужно проверить. Определите маленький кусочек. Попытка рефакторинга. Считаете ли вы, что это такое изолированное изменение, как вы надеетесь? Была ли цена, как вы ожидали? и главное... какие минусы есть? Есть вероятность, что ваш код работает хуже, чем существующие хранимые процедуры. Разработка "налога" это одно, а выполнение во время выполнения "налога" это совсем другое дело.
Занимайтесь бизнес-логикой хранимых процедур и пользовательского интерфейса отдельно. И возьми SP сначала. Один за раз:
- написать процедуру, которая вызывает SP
- испытать ад
- перенаправить любой код из SUT для вызова этой процедуры вместо SP
- запишите бизнес-логику в эту процедуру (конечно, продолжая проходить все тесты)
- бросить SP
Подходите к пользовательскому интерфейсу аналогично. Ни в том, ни в другом случае это не так просто, как кажется - отображение между SP и "обычным" кодом в лучшем случае несовершенно, - но я не знаю лучшего подхода.
Я защищаю не писать множество модульных тестов, а затем рефакторинг; скорее, протестируйте код, который будет реорганизован сегодня. Несколько юнит-тестов, немного рефакторинга; вспенить, промыть, повторить. Вы можете прерывать в любое время и иметь лучшую систему, чем когда вы начали; нет большой задержки между выполнением изменений и получением результатов.
Я бы полностью согласился с ответом piotsrz - хороший, всеобъемлющий набор модульных тестов - это именно то, что вам нужно, чтобы помочь сохранить поведение при рефакторинге. Добавьте эти тесты в систему непрерывной интеграции, чтобы вы могли быстро получать отзывы о каждом коммите от каждого разработчика.
Еще одна хорошая книга на эту тему - " Рефакторинг в паттерны", в которой описаны несколько итерационных методов для архитектурных преобразований, сохраняющих поведение.