Я часто прошу других инженеров описать мне, как выглядит «хороший код». Это также довольно хороший вопрос для собеседования, поскольку он дает интервьюеру представление о том, что кандидат считает ценным в своей работе. В некотором смысле это показатель их мастерства кодирования — то, что они считают основными принципами и как они будут проверять код других членов вашей команды.
В своем ответе они, скорее всего, поднимут понятие «чистый код» или «код, который легко читать». Вот где я люблю бросать им вызов:
«Что на самом деле означаетчистыйкод? Что делает кодлегким для чтения?»
Ответы, которые вы получаете, могут сильно различаться в зависимости от опыта кандидата, и это может быть достойным способом отличить младших от старших. В ходе этого обсуждения неизбежно всплывает множество понятий: документация, комментарии, тесты, функциональное и объектно-ориентированное. программирование, композиция и наследование, линтинг, стилизация кода, микросервисы и монолиты, имена файлов, структуры каталогов и т. д. Сегодня я хочу сосредоточиться только на одной области «чистого кода». Я думаю, что это принцип, который большинство инженеров усваивают в начале своей карьеры — СУХОЙ код.
СУХОЙ
СУХОЙ¹ (Не повторяйся) и представляет собой простой принцип — избегайте повторения кода в пользу абстракций или нормализации данных. Мне нравится недавний шуточный твит от Кэт Мэддокс, иллюстрирующий это:
Хотя этот пример глупый, я помню, когда впервые учился программировать, я делал что-то очень похожее для решения некоторых довольно простых проблем. DRY — хороший принцип для младших инженеров, поскольку он поощряет критическое мышление и изучение возможностей языка программирования, с которыми вы, возможно, еще не знакомы. Очень приятно иметь возможность взять 20 строк кода и сократить их до 1 или 2. Это приятно, и кажется, что вы создали более чистый и простой код. DRY вызывает привыкание, и мы несем этот принцип с собой в своем наборе инструментов в наши карьеры.
По мере того, как вы пишете больше производственного кода и работаете в больших командах, я думаю, что СУХОЙ код начинает становиться слишком грубым инструментом. Во многих случаях СУХОЙ код действительно ужасен и приводит к коду, который трудно поддерживать, трудно тестировать и трудно читать. Это так СУХО, что натирает²! Хороший пример тому — тесты³. СУХОЙ код абсолютно неуместен в модульных тестах, где неправильная абстракция (и я бы сказал, любаяабстракция)затруднит чтение ваших тестов и может затруднить отслеживание сбоев. вниз. Я большой поклонник кода, который можно легко удалить. СУХОЙ код часто очень трудно удалить, не сломав что-нибудь по пути. Я вижу, что это чувство все больше и больше ощущается другими членами сообщества.
DRY имеет свое место. Он отлично подходит для проектирования API, алгоритмов, обработки событий — и это лишь некоторые из областей. Это также важный основной принцип при работе в крупной компании. Вероятно, вы не хотите, чтобы каждая команда создавала одно и то же несколько раз, поэтому важно установить шаблон повторного использования кода между командами или между разработчиками. Итак, в каких случаях DRY нас подводит?
ВЛАЖНЫЙ
Ну… есть WET⁴ (Напиши все дважды). Название немного иронично, но цепляет. Принцип заключается не в том, чтобы буквально дублировать логику (как в примере isEven), а в том, чтобы использовать дублирование в тех местах, где абстракция на самом деле была бы вредной. Я думаю, что есть смысл иметь принципы кодирования WET в своем наборе инструментов, даже если это приводит к тому, что вы буквально копируете/вставляете разделы кода.
Я думаю, что модульные тесты (опять же) — отличный пример, когда запись всего дважды, а затем обновление одной переменной или одного аргумента вполне приемлемо и даже предпочтительно. Если тест устарел или устарел — его очень легко удалить, а потери производительности, которые вы платите за дублирование, минимальны.
WET — это полезная парадигма, чтобы держать свой задний карман исключительно в качестве решения плохой абстракции.
«Дублирование намного дешевле неправильной абстракции.»⁵— Санди Мец.
Еще есть DAMP Не абстрагируйте методы преждевременно (согласно Мэту Райеру⁶). и AHA Избегайте поспешных абстракций (по Кенту К. Доддсу⁷). Лично я предпочитаю использовать аббревиатуру DAMP для чего-то другого (см. ниже), но предлагаемые здесь идеи такие же. Вместо того, чтобы спешить с созданием умной абстракции и поиском способа сокращения кода — просто даже не заморачивайтесь. Дублируйте его. Используйте его в производстве некоторое время. Заставьте других людей использовать его. Затем проводите рефакторинг только тогда, когда возникает реальная проблема.
Я обнаружил, что инженеры часто в конечном итоге создают себе проблемы, которых еще не существует. «Но мы должны построить X. Что, если наши пользователи сделают Y, и все сломается?» А если нет? Возможно, вы тратите все свое время на создание чего-то, что никто не собирается использовать. Не поймите меня неправильно, важно уметь предвидеть проблемы, которые могут возникнуть у вас с архитектурой кода и системами проектирования, которые просуществуют более нескольких дней, но есть такая вещь, как чрезмерная инженерия, и мы должны быть готовы к этому. помня об этом. Это искусство. Трудно предсказать, какой тип абстракции будет слишком маленьким, слишком большим или в самый раз. Я думаю, что СУХОЕ, встроенное в наши умы с раннего образования, приводит нас к чрезмерной абстракции, и в целом оправдана некоторая ВЛАЖНОСТЬ.
ВЛАЖНЫЙ
Тогда есть DAMP Описательные и значимые фразы (как у Джея Филдса⁸). Что немного отличается, но также очень применимо. Для меня DAMP меньше фокусируется на плохих абстракциях и больше на чистоте и организации кода.
Хорошим примером, иллюстрирующим это, является как Facebook называет свои 30 000 компонентов React⁹.
Одним из побочных эффектов СУХОГО мышления является то, что вы склонны применять тот же принцип к другим частям кода: способу именования файлов, способу именования функций и переменных, способу управления структурой каталогов и т. д. к проблемам тоже. Я нашел полезными несколько основных принципов DAMPness:
- Не бойтесь писать длинные подробные комментарии, если вам нужно объяснить «почему вашего кода»¹⁰
- Не бойтесь использовать длинные описательные имена для файлов, функций, компонентов и т. д.
- Не бойтесь использовать длинные имена переменных (особенно для констант).
- Не думайте о том, чтобы сделать компоненты повторно используемыми¹¹, а вместо этого сосредоточьтесь на том, чтобы сделать их простыми в использовании и обслуживании.
Я согласен с Дэном Абрамовым, когда он говорит¹², мы должны перестать зацикливаться на написании чистого кода. К тому времени, когда вы приступите к работе и у вас будет большая команда, ваш код уже не будет чистым. Сосредоточьтесь на том, чтобы ваш код работал (самое главное), легко читался и легко удалялся. У вас всегда будет неправильная абстракция, и даже если вы сделаете ее правильно — новый язык, или парадигма, или фреймворк, или платформа сделают ваш код полностью устаревшим менее чем за десять лет. Попробуй сам. Напишите какой-нибудь код, который вы считаете красивым и чистым, и поставьте себе напоминание снова взглянуть на него через 2, 3 или 5 лет. Я гарантирую, что у вас будет совсем другая точка зрения.
Создайте то, что будет легко изменить, а не то, что выдержит испытание временем.
- [1]: https://en.wikipedia.org/wiki/Don%27t_repeat_yourself
- [2]: https://www.youtube.com/watch?v=-NP_upexPFg&feature=youtu.be&t=1043
- [3]: https://stackoverflow.com/questions/6453235/what-does-damp-not-dry-mean-when-talking-about-unit-tests
- [4]: https://twitter.com/CodeWisdom/status/1198654768228511754
- [5]: https://www.sandimetz.com/blog/2016/1/20/the-wrong-abstraction
- [6]: https://twitter.com/matryer/status/1082278413510082560
- [7]: https://kentcdodds.com/blog/aha-programming#aha-
- [8]: http://blog.jayfields.com/2006/05/dry-code-damp-dsls.html
- [9]: https://www.reddit.com/r/reactjs/comments/6al7h2/facebook_has_30000_react_components_how_do_you/dhgruqh/
- [10]: https://mobile.twitter.com/EvHaus/status/1285954988242427908
- [11]: https://medium.com/the-non-traditional-developer/stop-writing-reusable-react-components-bd649cba2700
- [12]: https://overreacted.io/goodbye-clean-code/