2010-01-20 2 views
36

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

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

Теперь мой вопрос: Как я могу научиться справляться с плохим кодом? Как я могу научиться понимать огромные кодовые базы, а затем реорганизовывать их части, не нарушая работу, которая уже работала и не превышала предельный срок? Есть ли литература, которую вы можете порекомендовать? У вас есть общие советы для меня?

+0

Сообщество wiki? – Thilo

+0

Да, сообщество wiki! – bitbonk

ответ

19

Michael Feathers написал хорошую книгу по этому вопросу.

Working Effectively with Legacy Code.

Еще одна интересная книга Мартина Фаулера, Кента Бека и других:

Refactoring: Improving the Design of Existing Code.

+0

+1 для WELC - это классическая ссылка - по уважительной причине! - именно по этим вопросам. –

+2

Книги - это пара. Я рекомендую сначала прочитать * Рефакторинг *. Это будет вдохновлять и разочаровываться, потому что вы скажете: «Но мне нужно внести изменения, чтобы проверить его. Как мне это сделать, не нарушая код?» Вот где входит книга «Перья». –

21

Общий совет:

if (it is working) 
    Do (not touch it); 
else 
{ 
    Make (as few modifications as possible) 
    Or (it will stop working at all); 
} 

Это опыт поколений.

+15

+1. Печально, но верно. – Thilo

+7

Согласен, но разве это не мешает вам видеть, как это плохо? Это похоже на то, что я должен исправить это! – Strawberry

+2

Каждый программист имеет это;), но время, и, следовательно, деньги не позволят это. – Oxymoron

6

Когда мне приходится иметь дело с добавлением функциональности плохой код, мой обычный подход:

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

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

+7

Очень часто код настолько плохо спроектирован, что трудно писать тесты для него вообще. – bitbonk

+0

Всегда можно написать хотя бы * некоторые * тесты. –

+2

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

4

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

Кроме того, прежде чем приступать к сложному ОО, попробуйте разбить методы и функции на более мелкие. Обеспечение определенного уровня атомарности в каждой из функций, что делает код намного легче поддерживать, читать и управлять. Это все о мелочах, разбивайте его на логические единицы операции, я делаю действие рефакторинга по методу 1k строк. Он делает всевозможные причудливые вещи. Моя первая цель состоит в том, чтобы получить как можно больше материала из меньших частей, когда это будет сделано, я начну думать о лучшем дизайне OO, что намного проще, потому что я гораздо лучше разбираюсь в вещах.

Аспирин хорошо работает.

8

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

Pex - это инструмент, который мне пригодится (если вы в мире .NET) для создания тестов для устаревшего кода.

Унаследованный код == код без тестов!

Kindness,

Dan

0

Это зависит от ряда факторов, но наиболее важным является, если у вас есть власть, чтобы изменить его.

В случае, если вы это сделаете, отредактируйте его. Например, переименуйте классы/функции/переменные. Извлеките и обобщите функциональные возможности. См. Рефакторинг: Improving the Design of Existing Code (Библия для предмета). Прежде чем вы начнете делать это, убедитесь, что код находится в правильном управлении версиями (VC) и имеет хороший набор тестовых примеров. VC позволяет вам откатываться назад, а тестовые случаи помогают поймать неожиданные побочные эффекты.

Я предлагаю управление распределенной версией, такое как Mercurial/Bazaar и Git, потому что он очень рефакторинг не точно структурирован как добавление функций.

Если не было никаких проверок, вы должны их создать. Прочитано Working Effectively With Legacy Code. Особенно о «Уплотнении» (не о сиамской кошке: p).

Если вы не создаете API-интерфейс обертки, который является более чистым.

Например:


Old code ==================== 
const ACT_SHOW = 'show'; 
const ACT_HIDE = 'hide'; 
function int DoThing(Object $Obj, Stirng $Action, Object $Param1, Object $Param1) { 
    ....; 
} 
Added code ================== 
enum Actions { 
    show, hide; 
}; 
class ActionDoer { 
    private obj; 
    ActionDoer($Object) { 
     this.obj = $Object; 
    } 
    function int act(Actions $Action, $Param1, $Param1) { 
     this.act($Action.toString(), $Param1, $Param1) ; 
    } 
    function int act(String $Action, $Param1, $Param1) { 
     DoThing(this.obj, $Action, $Param1, $Param1) ; 
    } 
    function int show() { 
     this.act(Actions.show, null, null); 
    } 
    function int hide(Color $ToBGColor, long $FadeTime) { 
     this.act(Actions.hide, $ToBGColor, $FadeTime); 
    } 
} 

Таким образом, старый код не прикоснулся и расширение может быть сделано с помощью нового кода. Хорошим примером этого метода является jQuery, где старый (по умолчанию) способ доступа к DOM является болезненным.

Надеюсь, это поможет.

1

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

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

3

В настоящее время я в этой ситуации. Мой подход, чтобы ответить на некоторые вопросы, прежде чем прикасаться код:

  1. это код действительно, что плохо? Если да, каковы распространенные ошибки? ==> возможно сосредоточиться на первых
  2. Каков основной поток времени выполнения в коде? Возможно, вы можете отбросить от него несколько конструкций.
  3. Попробуйте сложить/модулировать код, не меняя его. Это приводит к некоторому уменьшению взаимозависимостей.
  4. Попробуйте выполнить код с помощью тестов. Если база кода запутана без надежды: используйте что-то вроде PowerMock, чтобы имитировать объекты, которые еще не нуждаются в изменении.
  5. Имейте доступную среду интеграции, в которой вы можете протестировать изменения в производственной среде.
  6. Не уклоняйтесь, чтобы переписать части базы кода. Но постарайтесь не реализовать слишком много нового материала в нем
  7. Try, чтобы объединиться, обсудить конструкций, принципы решения

Это тяжелая работа, и никто не будет благодарить вас за это. Гордитесь небольшими улучшениями и получите хорошую работу :)

Смежные вопросы