Часть 1

Мне две недели после окончания трехмесячного курса иммерсивного кодирования в Makers. Для подготовки к техническим собеседованиям нам поставили печально известное ката Gilded Rose. Цель первой пары абзацев этого блога - побудить других, кто учится программировать, особенно будущих разработчиков, вести блог.

4 месяца назад я работал над проблемой, поставленной Джошем Чиком в его учебниках по ruby-kickstart (примечание: если вы новичок в разработке и хотите изучить Ruby, это отличное место для начала). Раздраженный проблемой и неспособный понять, как разблокировать себя, я в конечном итоге скопировал и вставил весь вопрос в Google.

К моему большому удивлению, у меня получился матч.

Эби Трэверс, бывший Создатель, на протяжении всего своего мыслительного процесса говорила именно об этой проблеме. В то время я путешествовал один по Южной Америке, и всего за неделю изучения кода у меня не было инструментов отладки, которые я с тех пор изучил в Makers. У меня не было друзей в моем часовом поясе. Я чувствовал себя растерянным.

Было огромным утешением знать, что кто-то другой боролся точно так же, но, что наиболее важно, она посоветовала написать о своем мыслительном процессе как о разблокирующем инструменте. Это был самый полезный совет, который я получил до того, как прибыл в Makers, и много раз разблокировал меня до и во время курса.

Так что, если вы читаете это и только начинаете свое путешествие по программированию, пишите в блог.

Даже если вы не публикуете это, ведите блог.

Запишите все свои мысли о проблеме и представьте, что кто-то их прочитает. Он укрепляет структуру вашего разума, которая может позволить вам взглянуть на проблему под другим углом и увидеть, казалось бы, очевидные ошибки. Если вы не можете объяснить код, попробуйте поиграть с ним, пока не сможете, ничего страшного, если ваше лицо зеленое.

Часть 2 - Позолоченная роза

Этот раздел блога - всего лишь мой мыслительный процесс при решении этой проблемы. Я написал это только для себя, но не стесняйтесь читать :). Вот мое репозиторий на гитхабе.

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

Задача - добавить новый элемент. Идея состоит в том, что сначала вам нужно извлечь длинный искажающий метод под названием «updateQuality», чтобы сделать базу кода более гибкой. В Makers нам нравится DRY-код, который следует принципу единой ответственности, и TDD или умри. Это упражнение, демонстрирующее ценность следования этим принципам.

Я выбрал JavaScript, так как это язык, который мы нечасто использовали, и я хотел испытать себя.

Мой процесс:

Шаг 1 - Схема

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

Шаг 2. Напишите набор тестов функций

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

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

Шаг 3 - Вернуться к доске для рисования

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

Шаг 4 - моя первая ошибка

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

Вместо этого на шаге 4 было написано модульное тестирование для foo, сохраняя сначала все поведение «update» в классе foo.

Шаг 5 - тесты становятся зелеными

Шаг 6 - рефакторинг

Шаг 7 - повторяйте шаги с 4 по 6, пока не будут запущены все классы элементов.

Шаг 8 - Интеграционные тесты

Это был новый термин для меня (хотя я открыл для себя этот термин только после реализации процесса). Я скорректировал свой модульный тест для Foo, чтобы разрешить извлечение поведения «обновление». Я хотел, чтобы класс Foo понимал логику того, насколько должно обновляться качество при каждом условии. Однако я хотел извлечь возможность обновления и сделать это поведение доступным для всех классов элементов. Это было стремление к СУХОМУ коду с единственной ответственностью.

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

Шаг 9 - модульные тесты для класса обновления… красный, зеленый, рефакторинг

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

Шаг 10 - повторите шаг 8 для остальных элементов

TDD включает поведение обновления в каждый из классов элементов, чтобы ОСУШИТЬ код.

Шаг 11 - интегрируйте мой новый код с устаревшей кодовой базой.

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

Шаг - 11 обзор тренера

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

Шаг - 11 реализация обратной связи

В пятницу днем ​​в 16:00 я решил заняться реструктуризацией класса обновления. 39 из 42 моих тестов покраснели. Я работал лихорадочно в течение 40 минут, прежде чем, в конце концов, моя окончательная настройка отправила последние 12 тестов зеленым за один раз.

Момент чистого восторга, мои руки мгновенно взлетели в воздух, и мне пришлось подавить свой крик от радости.

Вот почему мы пишем код.

Спасибо за чтение! Если вам понравился этот пост, пожалуйста, похлопайте 👏, чтобы помочь другим найти его. Я также буду благодарен за ваш отзыв, если вы захотите поделиться.