Как провести рефакторинг тесно связанных классов?

Я пытаюсь реорганизовать большое тесно связанное приложение и сделать его более удобным и гибким.

У меня есть много модульных тестов, поэтому я надеюсь провести рефакторинг шаг за шагом.

Какие шаблоны проектирования и рефакторинга следует рассмотреть для реализации/применения для выполнения этой задачи?

Я могу думать о некоторых:

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

ОБНОВЛЕНИЕ

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


person dr. evil    schedule 27.04.2009    source источник
comment
Я думаю, вы можете найти книгу (просмотреть в Интернете) Программирование на основе событий: получение событий до предела Не принимайте название за чистую монету - в первой главе дается проницательное описание и метод, с помощью которого можно уменьшить/переключить связь на меньшие формы связанного поведения.   -  person Paul Sullivan    schedule 30.10.2011


Ответы (6)


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

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

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

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

person Jeff Yates    schedule 27.04.2009
comment
@Jeff Джефф Я добавил обновление к вопросу, объясняющему, почему я это делаю. - person dr. evil; 27.04.2009
comment
Честно говоря, если есть способ избежать этого, я планирую избегать этого по крайней мере еще пару месяцев, так как я тороплюсь с этим приложением. Однако похоже, что мне нужно разделить классы для реализации системы плагинов. - person dr. evil; 27.04.2009

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

Это тоже очень хорошая книга. Я определенно включил бы ее вместе с Code Complete, Шаблоны проектирования и Pragmatic Programmer в список книг, которые должны быть в арсенале каждого разработчика. библиотека.

person Adam Jaskiewicz    schedule 27.04.2009
comment
Я читал Code Complete и Pragmatic Programmer. В настоящее время изучается работа с устаревшим кодом, и в нем есть целый раздел, посвященный методам нарушения зависимостей. - person dr. evil; 27.04.2009
comment
Да, это так. Из конца книги: Рассматриваемые темы включают... улучшение дизайна... добавление унаследованного кода в систему тестирования... написание тестов, которые защищают вас от появления новых проблем... работу с приложениями, которые, кажется, не имеют никаких проблем. структура... каталог из двадцати четырех методов взлома зависимостей. - person Adam Jaskiewicz; 27.04.2009

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

person tvanfosson    schedule 27.04.2009

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

person C. Ross    schedule 27.04.2009

Несколько полезных советов от Phlip: Рефакторинг низко висящих фруктов

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

person Carl Manaster    schedule 27.04.2009

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

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

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

person dr. evil    schedule 29.04.2009