Преодоление дурной привычки «исправить это позже» - PullRequest
8 голосов
/ 21 июля 2009

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

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

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

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

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

Ответы [ 9 ]

12 голосов
/ 21 июля 2009

Я использую совершенно противоположный подход, когда пишу что-то на лету без большого этапа проектирования. То есть я пишу основную функцию так, как она будет выглядеть «в идеальном мире», используя воображаемые объекты и методы, затем создаю скелеты всего, чтобы программа компилировалась, затем возвращалась и заставляла работать. Это обеспечивает модульную конструкцию, а высокоуровневый код очень прост для понимания. Во всяком случае, недостатком является то, что код может стать слишком модульным, так как заманчиво писать doFoo () вместо реализации встроенного foo.

5 голосов
/ 21 июля 2009

«Сначала мы приобретаем привычки, а потом нас».

Это похоже на хорошие и плохие привычки. Звучит так, будто тебя захватил плохой.

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

3 голосов
/ 21 июля 2009

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

2 голосов
/ 21 июля 2009

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

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

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

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

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

1 голос
/ 21 июля 2009

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

0 голосов
/ 21 июля 2009

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

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

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

0 голосов
/ 21 июля 2009

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

0 голосов
/ 21 июля 2009

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

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

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

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

0 голосов
/ 21 июля 2009

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

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

...