Преодолеть вредную привычку исправлять это позже

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

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

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

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

Это хорошая идея? Любые другие предложения?


person Community    schedule 20.07.2009    source источник
comment
Недавно я задавал аналогичный вопрос о планировании проекта, но у нас немного разные проблемы. Возможно, какие-то ответы там могут быть вам полезны. stackoverflow.com/questions/1100819 /   -  person Victor    schedule 21.07.2009
comment
Награждаю себя шоколадом.   -  person Maxpm    schedule 30.11.2010


Ответы (8)


«Сначала мы формируем наши привычки, затем они формируют нас».

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

Практикуйтесь быть более модульным заранее, пока это не станет «именно так, как я делаю».

person duffymo    schedule 20.07.2009

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

person Stefano Borini    schedule 20.07.2009

Я считаю, что дисциплина TDD Red-Green-Refactor творит чудеса.

person Avdi    schedule 20.07.2009

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

Мой подход сверху вниз. Я пишу

while( obj = get_next_obj(data) ) {
  wibble(obj);
  fumble(obj);
  process( filter(obj) );
}

и только позже начать писать все эти функции. (Обычно они inline и входят в безымянное пространство имен. Иногда они оказываются однострочными, и тогда я могу их удалить позже.)

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

person sbi    schedule 20.07.2009

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

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

person Mircea Grelus    schedule 20.07.2009

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

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

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

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

person Breton    schedule 20.07.2009

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

person MatrixFrog    schedule 21.07.2009

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

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

Хитрость заключается в том, чтобы провести рефакторинг как можно скорее, но не слишком рано. И часто, но не слишком часто. Как скоро и как часто? Вот почему это искусство, а не наука :)

person Larry Watanabe    schedule 21.07.2009