Я учусь в старшей школе и работаю над проектом на C # с моим другом примерно такого же уровня квалификации, как и я. Пока что мы написали примерно 3000 строк кода и 250 строк тестового кода за промежуток в 100 коммитов. Из-за школы я отложил проект на несколько месяцев, и недавно мне удалось снова его возобновить.
К тому времени, когда я собрал его, я понял, что написанный мной код был плохо спроектирован, например, включение избыточных потоков в рендере, плохая защита от гонок во взаимодействии между эмулируемым процессором, графическим процессором и игровым картриджем. , а также код, который просто избыточен и сбивает с толку.
Проблема в том, что я не закончил даже основную функциональность моей программы, поэтому я не могу по-настоящему реорганизовать ее, и я чувствую себя обескураженным, чтобы продолжать прекрасно осознавать, что дизайн моего кода имеет недостатки. В то же время я не хочу отказываться от проекта; достигнут значительный прогресс, и работа не должна пропадать даром.
Мне кажется, что у меня есть пара вариантов: просто завершить функционал, обойдя плохой дизайн, а затем рефакторинг, как только все заработает, остановить все и работать, чтобы распутать все до того, как остальная функциональность может быть завершена, начиная проект все так, чтобы он снова был свежим в моей памяти, или просто отказался от проекта из-за его чрезмерного размера (по сути, «назад к чертежной доске»).
Основываясь на опыте других в таких проектах, каковы пути возвращения себя на правильный путь? Исходя из ответов на этом сайте, общее согласие заключается в том, что переписывание, как правило, не нужно, но доступно, если код не может быть поддержан без чрезмерных затрат. Я искренне хотел бы продолжить этот проект, но в его нынешнем виде мой код разработан недостаточно хорошо, чтобы я мог продолжать его, и чувство уныния отвлекает меня от продолжения.
Ответы:
Если бы я был на вашем месте, я бы попробовал это так:
во-первых, завершить текущий проект - хотя бы частично - как можно скорее, но в рабочем состоянии . Возможно, вам нужно уменьшить свои первоначальные цели, подумайте о минимальной функциональности, которую вам действительно нужно увидеть в «версии 1.0».
тогда и только потом подумайте о переписывании с нуля (давайте назовем это «версией 2.0»). Может быть, вы можете использовать часть кода из V1.0. Возможно, после повторного сна из-за сложившейся ситуации, вы примете решение реорганизовать V1.0 и сохранить большую его часть. Но не принимайте это решение, пока у вас нет «доказательства концепции V1.0».
Работающая программа «1.0» - это то, что вы можете показать другим, даже когда код плохой (о чем никто не будет беспокоиться, кроме вас самих). Если в процессе создания V2.0 вы понимаете, что у вас не хватает времени, у вас все еще есть V1.0 как частичный успех, что значительно улучшит ваш моральный дух. Однако, если вы сначала не закончите V1.0, есть большая вероятность, что вы никогда не закончите V2.0, потому что когда вы пройдете половину пути, будет момент, когда вы снова будете недовольны дизайном, а затем? Будете ли вы снова отказываться от V2.0 и работать на V3.0? Существует высокий риск вхождения в этот бесконечный круг, никогда не заканчивающийся.
Лучше использовать это как возможность научиться достигать промежуточных целей, а не как возможность оставить проекты в незавершенном состоянии.
источник
Better take this as an opportunity to learn how to achieve intermediate goals, instead of an opportunity to learn how to leave projects in an unfinished state behind.
Готовые ИТ-проекты, даже неисправные, намного лучше, чем незавершенные.
Незаконченные тоже могут многому вас научить, но не так много, как готовые.
Вы можете не видеть это сейчас, но вы получаете огромное количество работы с даже неисправным кодом.
Мой голос идет за финиш, а затем, возможно, рефакторинг - если нужно. Когда вы начнете работать с большим количеством проектов, вы увидите, что на удивление часто та часть, которая «должна была быть подвергнута рефакторингу», остается неизменной годами, в то время как другие части расширяются.
С точки зрения трудоустройства, в большинстве случаев вы получите больше похвал за законченный проект.
источник
Я бы с радостью начал проект заново.
Вы студент, и вы все еще учитесь. Это ставит вас в совершенно иную позицию, чем вопрос, с которым вы связаны.
Вы не несете профессиональной ответственности за свой код; если бы вы удалили весь проект прямо сейчас и ушли, у вас не было бы никаких последствий. Это огромное преимущество для разработчика. В ответе на вопрос, который вы задали, эти разработчики пытаются поддерживать программное обеспечение, за которое люди платят деньги, и даже крошечные ошибки могут вызвать большие проблемы с клиентами, что делает опасным писать с нуля. У вас нет этой проблемы.
Как личный проект, это прекрасная возможность попробовать что-то новое и учиться на своих ошибках. Это здорово, что вы понимаете, что у вашего старого кода есть проблемы, потому что это означает, что вы научились делать лучше. Опыт проб и ошибок может быть неоценимым для начинающих программистов.
Ваш проект относительно небольшой, и у вас нет тестов. Несколько ночей может быть коротким, чтобы написать 3000 строк с нуля, тем более что у вас уже есть идеи о том, что будет лучше в следующий раз.
Работа с неработающей кодовой базой будет гораздо больше истощать ваш моральный дух, чем переписывание.
Кроме того, это может быть отличным шансом попробовать написать более модульную программу с юнит-тестами. Это облегчает понимание кода, если вы вернетесь к нему после долгого перерыва, и поможет предотвратить ошибки, которые вы можете случайно допустить из-за забывчивости.
Наконец, вот одно мнение о мудрости иногда делать шаги назад, чтобы делать большие шаги вперед.
источник
Вы, вероятно, все еще в «быстрой учебе» в части своего развития. Есть хороший шанс, что через несколько месяцев вы обнаружите, что ваш новый и удивительный дизайн ужасно сломан, и вы даже не знали, когда начинали.
Добейтесь успеха - это самая важная вещь, которую вам нужно выучить. Поверьте мне, я знаю множество людей (не только программистов), которые застряли в цикле «начинайте все с нуля, поскольку я многому научился до того, как начал работать над этим проектом». Проблема в том, что это никогда не кончится - пока вы не перестанете изучать новые вещи, а это не самое подходящее место :)
Это также важно для возможности на самом деле закончить что-нибудь. Начинать заново - это интересно, круто, весело ... но если вы только научитесь этому, вы никогда не сможете ничего закончить. Опять же, это не очень полезная способность, и на самом деле она не так хороша, как создание чего-то полезного (или забавного). Жизнь коротка, время ограничено, и вы не можете просто продолжать практиковаться без ощутимых результатов - вы сойдете с ума от этого. Если вы не можете начать работать, потому что просто не можете решить, какой подход выбрать, вы уже находитесь в опасной зоне.
Всегда будут импульсы, чтобы начать все сначала. Даже в учебной среде это, скорее всего, плохая идея. Это не означает, что вам нужно перенести каждый прототип в готовое к использованию приложение, и это далеко не так. Но вам нужно, по крайней мере, перейти к фазе работающего прототипа - это, скорее всего, поможет вам взбодриться, и это очень полезная черта для любого разработчика. Сделай вещи . И самое интересное в том, что вы быстро увидите, что с вашим прототипом можно сделать еще миллион забавных или полезных вещей, а не «переписать его с нуля», а во многих случаях даже рефакторинг. Все, что вы делаете, имеет свою стоимость - по крайней мере, вы могли бы сделать что-то еще в это время.
источник
Я придерживаюсь идеологии «Сделай это, сделай это правильно, сделай это быстро» в разработке программного обеспечения.
Прямо сейчас вы не завершили первый шаг. Сначала сделайте так, чтобы он работал, а затем вы можете беспокоиться о том, насколько уродлив ваш код. На самом деле создание рабочего продукта - одна из самых трудных задач для новых разработчиков, потому что они настолько замкнуты в попытках сделать свой код идеальным с первого раза, и поэтому они застряли в Оптимизации Ада и никогда не дойдут до конца. реализация всех функций. Вы должны научиться откладывать все эти заботы по поводу рефакторинга и оптимизации, чтобы вы могли просто сосредоточиться на том, чтобы заставить программное обеспечение работать. Как только вы получите больше опыта, вы, естественно, сделаете больше правильно с первого раза, поэтому потребуется меньше рефакторинга.
Имейте в виду: преждевременная оптимизация - корень всего зла ( хороший вопрос для программистов смотрите в этом прекрасном вопросе ). Если вы тратите слишком много времени на размышления о том, как улучшить ваш код, вы застреваете в параличе анализа . Это убивает проект. Лучше просто завершить проект, прежде чем пытаться его оптимизировать.
Процитирую великого мотивационного оратора: просто сделай это .
Как всегда, есть соответствующий xkcd:
источник
Перепишите это. Неработающий код имеет небольшое значение, а три тысячи строк - это не так много кода. Это займет почти столько же времени, сколько потребовалось, чтобы написать код, который у вас есть, и будет намного лучше. Я часто выбрасывал пятьсот или тысячу строк плохого кода, и часто переписывание занимает одну пятую длины.
Большинство понятий вокруг «не переписывать» относятся к большим системам, которые выполняют важные задачи и подвергаются постоянным изменениям для удовлетворения меняющихся требований. Переписать сложные системы в использовании редко удается.
Ваша ситуация полная противоположность. У вас небольшое приложение без пользователей, и единственными требованиями являются те, которые вы выбираете для реализации. Так что давай и переписать его.
источник
Перезапуск с нуля, как правило, является плохим шагом в реальных проектах, главным образом потому, что в реальных проектах накапливаются исправления ошибок, о которых не знает новый разработчик (например, см. « Что вы никогда не должны делать» , из блога Джоэла в блоге по программному обеспечению ).
Тем не менее, школьные проекты не наследуют такую историю и обычно начинаются с кодирования и проектирования одновременно с частичным знанием вычислений и отсутствием опыта. Я бы рассмотрел вашу первую версию в качестве прототипа, использованного в качестве доказательства концепции, которая потерпела неудачу, и я с радостью выбросил бы ее (см. Раздел «В чем различия между одноразовыми и эволюционными прототипами?», Чтобы обсудить одноразовые и эволюционные прототипы.)
Правильный дизайн созрел в вашей голове и не должен занимать много времени, чтобы записать его в коде.
источник
Я бы с уважением не согласился с предложениями, что переписать это плохая идея.
В области жизненного цикла программного обеспечения общепринято, что время и усилия, необходимые для исправления ошибки, увеличиваются на порядок для каждого слоя в жизненном цикле. То есть, если для исправления ошибки на уровне требований требуется 1 час, на разработку потребуется 10 часов, на тестирование кода - 100 часов, а на исправление ошибки - 1000 часов. Эти цифры могут показаться возмутительными, но в промышленности они считаются приблизительно правильными. Очевидно, меньше в меньшем проекте, но общая идея остается. Если у вашего проекта есть базовый недостаток дизайна, то более уместно назвать это опытом обучения и вернуться, пересмотреть свои первоначальные требования и перепроектировать.
Я также рекомендовал бы рассмотреть модель Test Driven Development с использованием структурированных модульных тестов. Они представляют собой боль и поначалу кажутся пустой тратой времени, но их способность обнаруживать ошибки, особенно при интеграции с чужим кодом, не может быть переоценена.
источник
Вы потеряли меня в этом предложении:
Я верю в принцип (изложенный в Systemantics ), что
Итак, написание сложной системы включает в себя
... т.е. следующие шаги:
Обратите внимание, что шаг 3 может включать в себя:
Кроме того, шаг 2 «Протестируйте его, чтобы убедиться, что он работает» может потребовать некоторого переписывания, если это не так.
Если бы я строил на гнилой кодовой базе, я бы не хотел добавлять дополнительную функциональность. Поэтому я был бы склонен запланировать что-то вроде «упростить существующую реализацию потоков» как следующую часть работы, которая будет реализована. Предполагая, что вы проходили тестирование, вы должны воспринимать это как упражнение по рефакторингу. Критерии успеха / выхода для этой фазы работы будут следующими:
Кстати, «тестирование, чтобы убедиться, что оно работает» не обязательно означает «модульные тесты» - когда структура команды проста, вы можете протестировать (простую) систему, используя (простые) системные тесты (вместо модульных тестов) .
источник
Одна из проблем, с которой вы сталкиваетесь, сталкиваясь с подобной проблемой, заключается в том, что вы эмоционально привязаны к коду, который вы так или иначе написали до сих пор.
Коллега сказал мне, что он писал программу, когда учился в университете, когда учился у известного профессора (я думаю, это был Дейкстра). Он попросил профессора взглянуть на кодекс, над которым он работал более месяца. Профессор спросил его, сделал ли он резервную копию, он ответил нет. Затем профессор удалил весь свой код и велел ему написать его снова.
Он был взбешен, но через 3 дня он закончил программу с более чистым кодом и меньшим количеством ошибок и меньшим количеством строк кода.
Постарайтесь честно оценить, какой вариант лучше всего подходит для времени, доступного для проекта.
3 варианта
Я работаю профессиональным программистом более 10 лет, и в своей работе я пришел к выводу, что последний вариант чаще всего выбирается, но это не всегда лучший вариант.
источник
Похоже, ваши навыки значительно выросли за этот период времени. Возможно, работа над этим проектом способствовала этому. Проектирование его снова как целенаправленного обучения было бы плодотворным.
Помните, что это не то, что вам нужно предоставить в качестве рабочей программы для клиента. Это было написано специально для практики. Так что, если вы не хотите практиковать проблемы с доставкой и некорректную доставку, я думаю, что вы в настоящее время находитесь на стадии разработки, где работа над «мышцами дизайна» окажется плодотворной.
Делая это, сосредоточьтесь на процессе проектирования и планирования, размышляйте над существующими вещами и размышляйте над тем, что вы понимаете лучше.
источник
Рефакторинг. Рефакторинг. Рефакторинг! Реорганизовывать !!!!
Честно говоря, независимо от того, насколько вы опытны, это общая проблема. Вы написали код, вы чему-то научились и хотите использовать новые знания в старом коде. Вы хотите сравнить старый код с новыми знаниями.
Это просто не сработает. Если вы сделаете это, ваше приложение / игра никогда не будет завершено. Вместо этого попытайтесь выделить свое время на проект, чтобы некоторые из ваших «задач» заключались в рефакторинге плохого кода. Допустим, например, у вас был ужасный метод сохранения игры. Продолжайте работать над самой игрой, но найдите время для рефакторинга (замены) этого ужасного метода. Старайтесь держать реакторы маленькими, и это не должно быть проблемой.
Когда вы попадаете в основную часть приложения, которая нуждается в рефакторинге, вы серьезно делаете это неправильно. Разбейте этот рефакторинг на более мелкие части. Попробуйте потратить семь часов на написание кода и один час на рефакторинг.
Когда вы закончите с проектом и нажмете «Заморозить функцию», вы сможете потратить немало времени на рефакторинг. Пока закончите игру, но все же попытайтесь изменить ее. Это лучшее, что вы можете сделать.
Там всегда будет что-то для рефакторинга.
источник
Я бы сказал, что это немного зависит от того, какой код у вас сейчас и где именно проблемы. То есть, если ваши основы хороши (правильный дизайн класса в большинстве частей, хорошая развязка / сплоченность и т. Д., Только несколько неудачных выборов, как упомянутые вами темы), то непременно получите базовую версию 1.0, а затем рефакторинг как завтра нет
С другой стороны, если это на самом деле просто куча уродливых соединенных друг с другом текстовых файлов, каким-то образом пропускающих компилятор, без какой-либо заметной структуры и т. Д. (Другими словами, опытный образец обучения на рабочем месте), тогда я предпочел бы удалить его и начать все сначала.
В следующей версии используйте гибкий подход: установите для себя фиксированную повторяющуюся временную шкалу, например, 2 недели или любую другую, соответствующую вашему графику. В начале каждого куска (назовем это спринтом) поставьте себе цели, которые достижимы за 2 недели. Идите и делайте их, старайтесь изо всех сил, чтобы это сработало. Установите свои цели так, чтобы через каждые 2 недели у вас было что-то, что можно показать другу, а не просто абстрактная внутренняя работа. Гугл "схватка" и "умная цель". Это все очень легко сделать, если вы один, просто лист бумаги с несколькими быстро отмеченными пунктами.
Если вы можете сделать это, тогда начинать сначала - это хорошо. Если в глубине души вы знаете, что после начала вы, скорее всего, окажетесь там, где вы сейчас находитесь, тогда придерживайтесь своего кода и заставьте его работать.
источник
Вы должны поставить себя на место работодателя.
Для большинства рекрутеров вы были бы наиболее ценными, если бы вы пошли следующим образом: - Завершите его со 100% тестами на новый код, который вы пишете. - Добавить тесты для старого (плохо спроектированного) кода. - Рефакторинг это для достижения того, что вы хотели в качестве дизайна.
Делайте все это с хорошим процессом управления версиями, ветками и тегами.
Переписывание часто является сексуальной идеей, но часто это идея, которая появляется у новичков, что довольно опасно в реальной жизни. Показ того, что вы более готовы улучшить качество работы, которую вы уже сделали, а то, что начинать с нуля - это хороший знак того, что вы серьезный человек.
Вы можете, конечно, переписать его, но тогда сделайте его другим проектом.
источник
Просто чтобы добавить некоторые из моего прошлого опыта в микс. Я работаю над сайд-проектом уже больше года, когда у меня есть несколько свободных минут. Этот проект прошел путь от простого испытательного стенда до статического класса к объектно-ориентированному тонкому облицовочному дизайну, которым он является сейчас.
На протяжении всех этих изменений я сохранял одинаковую функциональность кода, исключая исправления ошибок и преимущества в производительности (должен быть максимально быстрым). Та же самая база кода, хотя рефакторинг остался прежним, и поэтому я значительно улучшил ее, не переписывая код с нуля и тратя время.
Это означало, что я смог улучшить код быстрее, чем раньше. Это также означало, что когда я собирался, мне было легче сказать, что нужно удалить, то есть ненужные классы, и что может остаться легче, чем переписать старую идею, все еще в моей голове.
Поэтому мой совет будет сделать рефакторинг вашего кода и двигаться дальше, внося улучшения по мере необходимости. Хотя помните, что если вы решите переписать с нуля, вы должны взять хорошие идеи старого проекта и внимательно посмотреть на них, чтобы увидеть, где они имеют недостатки. Т.е. не просто скопировать старый код в новый проект.
источник
Ответ зависит от того, что я люблю называть «потолком сложности». По мере того, как вы все больше и больше добавляете в базу кода, она становится все более и более сложной и все менее организованной. В какой-то момент вы достигнете «потолка сложности», после чего продвижение вперед становится очень трудным. Вместо того, чтобы пытаться продолжать двигаться грубой силой, лучше сделать резервную копию, реорганизовать / переписать, а затем продолжить движение вперед.
Так что ваша кодовая база настолько плоха, что вы приближаетесь к потолку сложности? Если вы чувствуете, что это так, потратьте некоторое время на очистку и упрощение, прежде чем продолжить. Если самый простой способ очистить это переписать некоторые части, это нормально.
источник
Ни? Обе?
Продолжайте дальше, потратьте некоторое время на пересмотр существующего дизайна и некоторое время на добавление новых функциональных возможностей.
Если у вас грубые взаимодействия, это может быть хорошим началом («чрезмерное количество потоков в рендерере» звучит как неэффективность, а не что-то, что может вызвать проблемы с корректностью). Посмотрите, можете ли вы найти общий способ избавления от гонок (и, возможно, тупиков), или хотя бы несколько конкретных способов сделать это.
Я не знаю, в какой степени такие вещи, как детекторы тупиков и гонок, доступны для C #, но если они существуют, они могут быть полезны для выявления проблем и проверки работоспособности ваших исправлений.
Я обнаружил, что в целом у меня больше мотивации решать проблемы с кодом, который делает что-то полезное, а не выбрасывать его и начинать снова с нуля. Есть случаи, когда развитие выжженного поля (по аналогии с новым полем и коричневым полем ...) является более удовлетворительным, но это обычно для вещей, где существующий подход настолько далек от того, где он должен быть, что он больше не ошибается.
источник
Если ваш код является модульным, то вы должны быть в состоянии завершить остальную часть кода вокруг плохо написанных компонентов, а затем переписать плохо написанные компоненты, не затрагивая остальную часть кода.
В этом случае вам решать, когда вы переписываете плохо написанные компоненты. Если плохо написанные компоненты написаны так плохо, что готовый код не будет работать с ними, как они есть, вам нужно будет переписать их, прежде чем закончить оставшуюся часть кода.
источник
Первый вопрос, который вы должны задать себе: «Насколько плох этот недостаток?»
Что именно ты сделал не так?
Если что-то настолько плохое, что вы потратите сотни часов, пытаясь разобраться с проблемой, предоставив конфиденциальные данные (пароли / кредитные карты) или вызвав серьезную уязвимость, то, возможно, вам следует отредактировать это, но в большинстве случаев вы можете возьмите то, что у вас есть, доработайте и исправьте проблему позже.
Программисты любят улучшать свои приложения, желая, чтобы они были «лучшими, какие только могут быть», но это неправильный подход.
Если вы выпускаете свое приложение как можно скорее, даже если оно не на 100%, ошибки и все остальное, вы получаете ОБРАТНУЮ СВЯЗЬ от других, имея время для исправления ошибок и прочего в версии 1.1. Другие люди смогут помочь вам сделать приложение намного лучше, и вы, возможно, потратили впустую время, занимаясь тем, что людям не нравилось.
Так что в вашем случае, получите его, получите некоторую обратную связь, а затем вы можете структурировать версию 2.0 со всеми изменениями и исправить имеющийся у вас недостаток.
Еще одна вещь, которую нужно помнить, это то, что мы постоянно совершенствуемся. Существует поговорка, что если вы можете посмотреть на свой код год назад и увидеть, что он плохой, это означает, что вы все еще улучшаете, и это здорово.
источник
Это зависит от того, насколько испорчен ваш код.
Если вы допустили реальные ошибки n00b, которые делают ваш код слишком сложным или многословным, то я бы порекомендовал переписать эти части.
Если вы считаете, что у вас есть серьезные ошибки, которые вам все равно придется исправить, напишите несколько модульных тестов, которые могут проверить, исправили ли вы ошибку (... поскольку вы еще не можете запустить программу). Лучше исправлять ошибки рано, и определенно лучше исправлять ошибки, пока вы еще помните, что делает код.
Если вам не нравится, как эти методы вызываются, или к какому классу они принадлежат, или такие мелочи, просто используйте IDE. (Помните, что это C #, а не какой-то javascript, python, perl, php и т. Д.) Когда вы работаете над кодом, который использует уязвимый компонент, и у вас есть четкое представление о том, что этот компонент должен делать, затем рефакторинг, если ваша IDE делает это безболезненно.
В противном случае, запустите его и оттачивайте свои навыки в следующем проекте.
источник
Как полагают другие, поскольку это личный проект, а не (пока) профессиональный проект, я бы серьезно подумал о переписывании.
Тем не менее, вы можете использовать научный метод здесь, выполняя эксперимент. Во-первых, придумайте гипотезу. Мое было бы, "вероятно, пришло время переписать". Чтобы сэкономить время, снизить стоимость сбоев и несколько ограничить априорное смещение, прежде чем приступать к дальнейшему программированию, определите отрезок времени («временной интервал»). Я бы предложил, наверное, 4 часа настенных часов. Также определитесь с методологией оценки гипотезы. Поскольку ставки невысокие, я бы предложил в качестве методологии просто спросить себя: «Я рад, что сделал это?» Теперь начните эксперимент. После того, как вы выбрали временной интервал, какова оценка гипотезы? Например, из моего примера, вы рады, что начали переписывать сейчас, потратив на это 4 часа? Тогда это, наверное, правильный выбор.
Вы можете попросить все советы в мире, но нет ничего лучше, чем проверить гипотезу эмпирически.
Несколько причин рассмотреть выбор переписывания в качестве эксперимента:
Завершение чего-либо - хорошая идея, но не в вакууме. Если вы начнете переписывать, вы можете закончить что-то, завершив работу конкретного подмодуля. Вы можете установить это в качестве первой цели после вышеописанного эксперимента. Завершение еще не означает окончание вашего первоначального основного проекта. После того, как вы закончите модуль, закончите другой и т. Д., Пока вы не закончите переписывать всю область вашего исходного проекта, если хотите.
источник