зачем нужен кодстайл в веб верстке
Заметки о codestyle
Довольно часто сталкиваюсь с вопросом касательно качества кода: «Почему написано именно так, а не так?». И я объясняю каждый раз. Именно поэтому решил составить эдакую заметку с объяснениями.
Второй возникающий вопрос: «Где научился так красиво писать?». Ответ на который будет к концу статьи.
Довольно распространённая проблема при написании кода в том, что он выглядит фактически сплошным текстом, и содержит в себе проблемные места, усложняющие не только чтение, но и дальнейшее сопровождение. В таких случаях не стоит пренебрегать использованием переносов строк и дополнительными символами «пробела».
Вспомнился бородатый анекдот по реальным событиям:
Разработчик читает свой код, написанный:
— сегодня: отличный современный крутой код! Всегда бы так писал!
— вчера: так, я остановился вот здесь. Ага!
— на прошлой неделе: что я там делал-то.
— в прошлом месяце: так, где там задача с описанием?
— в прошлом году: ноги б переломать тому, кто этот код писал!
Недавно встретил такой участок кода (вставлю картинкой, чтобы не нарушить его вид):
Данный участок очень плохо читается. Приходится вычитывать каждое слово с целью понять что в нём происходит и не пропустил ли чего. Это происходит из-за большого объёма слов на достаточно маленьком участке и является проблемой.
Мы давно пережили времена недостатка места на дисках и не стоит дорожить лишними символами. Это обычная экономия на спичках. Зачем усложнять жизнь не только себе, но и тем, кто после Вас будет поддерживать этот код? Плохо какать там, где едят.
Помимо вставки дополнительных символов и переносов строк, старайтесь разделять код на логические блоки.
Для примера возьмём следующий участок:
В нём мы видим непонятный массив текста, который можно разбить на логические блоки, позволяя быстрее понять его смысл, значительно сократив время на его поддержку:
Заключение
Очень давно мне дали дельный совет:
Всегда пиши код так, будто поддерживать его будет неуравновешенный и склонный к насилию маньяк-психопат, который знает где ты живёшь.
И это единственное правило, помогающее писать чистый и красивый код на любом языке программирования.
Новый взгляд на code style
Как знания нейропсихологии могут помочь программисту в стилизации кода? До того, как заняться программированием, я очень долго и глубоко изучал нейропсихологию. Впоследствии эти знания помогли мне добиться высоких результатов в разработке за короткий промежуток времени.
В этой статье я хочу поделиться своим опытом и подходом к стилизации кода. Мы рассмотрим стилизацию со стороны программирования, а затем немного коснемся нейропсихологии для более глубокого понимания самого процесса и степени его важности для разработчика. Последний год я работаю в компании Secreate, где занимаюсь разработкой мобильных приложений на фреймворке React Native, поэтому примеры кода, приведенные в этой статье, будут на языке Javascript. Знания, полученные из этой статьи, можно будет легко применить к любому языку программирования. В конце статьи вас ждут полезные примеры стилизации кода. Приятного чтения!
Что такое стилизация
Каждый программист имеет свое представление о code style. Для меня стилизация — это набор правил для оформления, таких как: отступы, пробелы, переносы, последовательность и так далее. Тем не менее, каждый программист оформляет свой код по-своему. Давайте рассмотрим несколько примеров такого оформления.
Импорты
Некоторые программисты пишут их так:
Еще можно встретить такое:
Объявление функций
Часто встречается такое оформление:
Также можно встретить такое:
Тернарная условная операция
Можно встретить такое:
Подобных примеров может быть великое множество. Большинство разработчиков не придают должного значения правилам и пишут код так, как им хочется, не задумываясь о том, какие преимущества может дать грамотное использование стилизации.
Что стилизация может дать
Давайте сделаем небольшое отступление. Представим, что вы начинающий программист. У вас стоит задача разработать некий функционал. Вы долго писали код, завершили разработку и начинаете проверять функционал. И, о ужас, результат его работы не тот, который вы ожидаете. Начинаются поиски ошибки. Просматриваете беглым взглядом свой код, и вроде все верно. При внимательном и детальном изучении ошибка все равно не находится. Это продолжается еще несколько часов. В отчаянии обращаетесь за помощью к старшему коллеге, и менее чем через минуту он уже указывает пальцем на ошибку и предлагает варианты решения. После внесения изменений вы не верите своему счастью — все заработало!
Как же он смог найти ошибку так быстро? Предположим, что роль сыграл десятилетний опыт в разработке. За эти годы он наблюдал великое множество кода. Опираясь на свои знания нейропсихологии, я бы предположил, что за время работы у него очень хорошо сформировались и наладились нейронные связи в головном мозге. Но что же такое нейронные связи и для чего они нужны? Для того, чтобы получить ответ на этот вопрос, давайте разберем его на простом примере.
Представим, вы занимаетесь разработкой мобильных приложений. Вам поставили задачу разработать слайдер для выбора значения в определенных границах. Вы можете разработать его прямо на нужном вам экране. В этом случае, если вам понадобиться создать еще один слайдер, вам придется писать его заново. Или же вы можете один раз разработать библиотеку для вашего слайдера и использовать ее для ваших будущих проектов. Итак, вы выносите ваш слайдер в отдельную библиотеку (формируете нейронную связь).
На данном этапе ваш слайдер выполняет только одну задачу и выглядит всегда одинаково. В будущем у вас может появится необходимость разработать слайдер для другого приложения, который должен выглядеть иначе. Вы обращаетесь к вашей библиотеке. Получается, что наш первый слайдер нужно модифицировать. Тогда вы начинаете дорабатывать и улучшать свою библиотеку. Добавляете новые возможности: менять внешний вид слайдера, менять анимации, тем самым налаживая нейронные связи. Затем добавляете возможность создавать два бегунка и так далее. И когда снова возникнет необходимость в создании слайдера, просто обратитесь к вашей библиотеке с нужными параметрами и она сама сформирует слайдер. При этом она сделает это в сотни раз быстрее, чем если бы вы заново его разрабатывали.
Подобным образом работает и человеческий мозг. Постоянно совершая некое действие, вы формируете, а затем налаживаете нейронные связи вашего мозга. Иными словами, вы учите ваш мозг выполнять некие действия без участия вашего сознания. Так, при анализе кода мы формируем нейронную связь (создаем библиотеку). Затем при помощи правил стиля мы ее налаживаем (улучшаем библиотеку). Наш мозг способен на подсознательном уровне, самостоятельно обрабатывать всю полученную о коде информацию и найти все синтаксические, структурные и архитектурные ошибки буквально за доли секунды. Ведь не секрет, что подсознание работает во много раз быстрее, чем сознание.
Как она это делает
Объясню на простом примере. Предположим, ваш проект — это очень большой, сложный и витиеватый лабиринт, состоящих из множества секций. В какой-то из секций лабиринта обнаружили дефект. Ваша задача — добраться до этой секции и исправить ошибку. Вы сами строили этот лабиринт и, казалось бы, должны легко в нем ориентироваться. Но из-за большого количества поворотов и развилок вы с очень большой вероятностью можете в нем заблудиться и, соответственно, потратить очень много времени и сил. Теперь представим, что во время строительства лабиринта вы повсюду развесили таблички с указанием маршрутов. В таком случае вы не заблудитесь и легко доберетесь до любой точки вашего лабиринта.
Стилизация кода выполняет ту же функцию, что и таблички с указаниями. Иными словами, придерживаясь четких правил стиля, вы сможете легко ориентироваться в вашем коде и быстро подмечать любые ошибки. К примеру, если вы допустите структурную ошибку или даже опечатку, ваш мозг среагирует на нее таким образом, как будто привычная синяя секция лабиринта вдруг стала желтой. И не заметить такое будет очень сложно, ведь на табличке написано “синяя секция”.
Итоги
Когда я только начинал программировать, я вообще не задумывался о важности стилизации и относился к ней как к личным прихотям каждого программиста. Я думал, что каждый пишет код так, как хочет и стиль несет в себе исключительно эстетическую функцию. Но как-то раз я столкнулся с проблемой, которая раз и навсегда поменяла мои взгляды на code style.
Я разрабатывал новый функционал, и при подключении его к приложению данные не отображались. Я провозился с этой ошибкой больше часа, пока не заметил, что допустил небольшую опечатку. Потеряв много времени и нервов на ее поиски, я начал думать о том, как можно избежать подобных ошибок в будущем. На помощь пришли познания в нейропсихологии. Я стал разрабатывать для себя правила оформления кода, стилизовать его. Столкнувшись с подобной с проблемой в следующий раз, ее решение заняло у меня всего пару минут. В тот момент я осознал всю важность стилизации.
Ниже я привел несколько правил стиля, которыми я пользуюсь. Надеюсь, эта информация поможет многим начинающим или даже опытным программистам избежать множества ошибок и повысить качество кода.
Длина строки
Длина строки не должна превышать ширину туннеля прямого взгляда. То есть очень важно, чтобы для прочтения строки не приходилось смещать фокус взгляда. В противном случае фоновый процесс анализа кода (на подсознательном уровне) будет прерван и придется заново искать нужное место в коде и возобновлять этот процесс.
Уровни вложенности
Выделяйте уровни вложенности отступом в 2 пробела. Так вы всегда будете знать, дочерний это элемент или отдельный.
Объявление объекта
Если полей в объекте немного и строка не превышает нужную ширину, то отделяйте поля пробелом.
Если же полей много, определяйте их в столбик, по одному полю на строку и не забывайте ставить запятую после каждого поля.
Объявление функции
Отделяйте пробелом закрывающую круглую скобку от открывающей фигурной скобки. Тело функции переносите на следующую строку.
Ключевые слова
Отделяйте пустой строкой ключевые слова.
Отделяйте пустой строкой объявление функций и разнотипные действия
Последовательность элементов
Соблюдайте строгую последовательность элементов.
Пример класса расширяющего React.Component:
Отделяйте пробелом самозакрывающий тэг
Переносите props’ы на следующую строку, если их больше одного
Длинные условия
Разбивайте длинные условия на несколько строк, начиная каждую строку с условного символа.
Отделяйте пробелами условные символы
Зачем нужен кодстайл в веб-вёрстке
Представьте, что к вам подошел иностранец и задал вопрос. Скажем, про тонкий зелёный длинный маленький предмет. Первая мысль, которая приходит в голову: все слова знакомы, но с описанием предмета что-то не так. Интуитивно хочется расставить эти прилагательные по-другому (например, маленький зелёный тонкий длинный). Это называется порядком однородных определений.
Как и прилагательные в речи, CSS-свойства в коде также могут выглядеть не на своём месте, если их не выстроить в нужном порядке. Порядок свойств позволит программистам, работающим над одним проектом, понимать чужой код и правильно оформлять свой. Осталось договориться о том, как располагать свойства, чтобы не казаться друг другу иностранцами.
Для такой цели и был придуман кодстайл (набор правил и соглашений, используемых при написании исходного кода на некотором языке программирования).
У многих крупных компаний, таких как Яндекс, Google, рекомендации по оформлению кода опубликованы и доступны всем желающим. В фирмах поменьше могут быть внутренние инструкции, иногда единый стиль кода оговаривается устно (бывает и такое).
Как выглядит наш сайт кодстайла
Как выглядит наш сайт кодстайла
Это лишь выжимка основного из всех правил, обязательно ознакомьтесь со всеми правилами и применяйте их.
Порядок | Группа свойств | Используемые свойства |
---|---|---|
1 | Позиционирование | |
2 | Блочная модель | position: relative; left: 0; right: 0; top: 0; bottom: 0; |
3 | Типографика | display: flex; align-items: center; margin: 10px; padding: 10px 20px; border: 1px solid red; width: 200px; height: 100px; box-sizing: border-box; |
4 | Оформление | font-family: Arial; font-size: 25px; font-style: italic; text-decoration: none; color: red; background: red; opacity: 1; |
5 | Анимации | transform: translateX(5px); animation: shake 0.3s infinite; |
Правила JS не сильно отличаются от HTML и CSS, разве что само применение зависит от итогового синтаксиса. Например, есть такие правила, присущие только для JS, как:
Ну а полный кодстайл вы можете (и очень рекомендуется) изучить по ссылке.
Code style как стандарт разработки
Давайте сразу, это не про скобочки. Здесь речь пойдет о том, как работает наш мозг и почему code style помогает обеспечивать линейное развитие проекта, значительно ускоряет адаптацию новых сотрудников и, в целом, формирует и воспитывает культуру разработки. Я постарался собрать в одной статье несколько исследований и принципов, посвященных работе мозга разработчика, и тому, как программисты читают код, а также поделился результатами личного эксперимента.
Интересно? Добро пожаловать под кат.
Привет! Меня зовут Антон, я пишу backend в ManyChat. Недавно у нас прошел митап, посвященный PHP-разработке, где я рассказал доклад про code style как один из стандартов разработки. По фидбеку, он отлично зашел гостям мероприятия, и мы решили сделать расшифровку доклада на Хабр. Для тех, кто особенно ценит эффект личного присутствия и больше любит смотреть видеозапись, чем читать тексты, у нас велась трансляция, которая доступна и сейчас. Найти ее можно по ссылке. Тем, кто любит лонгриды, добро пожаловать дальше.
Наш мозг — нейронная сеть
Начать стоит с описания, как вообще это работает и зачем вообще нужно всё то, о чем я расскажу позже. Многие из вас знакомы с понятием нейронной сети, или как минимум, слышали это словосочетание, которое несколько лет было чуть ли символом хайпа в IT-пространстве и маркетинге. Даже сейчас многие компании добавляют “AI based” на свои продукты, как наклейку “Без ГМО” на пельмени. Нейронная сеть работает по принципу распознавания образов и крайне эффективна при работе с однородными данными. Это изображения, видео, звук и т.д. Основной момент, который имеет отношение к стилизации кода — это принцип, на котором они были построены. Перцептроны, ячейки сети, были описаны как процессы работы мозга и заложены задолго до того, как они смогли быть реализованы в функциональную, работоспособную и эффективную сеть из-за слабых вычислительных мощностей. Наш мозг, хоть и значительно мощнее, работает схожим образом. Как следствие, человек использует мощности обученной нейронной сети от рождения и до самой смерти, а обучение идёт практически бесшовно.
Итак, мы воспринимаем только образы. Для мозга не существует текстов, звуков и прочего – все это мы воспринимаем только после декомпозиции. Грубо говоря, мы разделяем образы “попиксельно”, складываем в память и потом при помощи ассоциативного мышления узнаем различные объекты. Благодаря этому мы можем понять, бежать ли нам от змеи или садиться на велосипед и нажимать на его педали. Перед вами схема стандартного перцептрона, которая иллюстрирует, как происходит классификация объектов. Для тех, кто не знаком с принципом работы перцептрона, может выглядеть немного хаотично. Но именно благодаря такой схеме балансировки и взвешивания нейронная сеть распознает образы, быстро и эффективно.
Из программирования можно вспомнить принцип DuckType, когда считается, что если объект плавает как утка, летает как утка и крякает как утка — это утка. Своеобразная аппроксимация детектирования объектов. И для нашего мозга распознавание объектов происходит моментально. Обучение же значительно более длительный процесс. Поэтому можно представить этот процесс также, как и обучение еще маленького ребенка, который только учит слова. Вы берете яблоко, показываете и говорите: «Это яблоко». Берете другое и снова повторяете: «Это яблоко».
И так до закрепления результата. Зеленые, желтые, красные, шарообразные, вытянутые, с черенками и без, черно-белые. Год за годом, ребенок наращивает свою базу на основе эмпирических знаний. Я думаю, принцип понятен. Тоже самое мы делаем когда обучаем нейронную сеть. От объекта к объекту или, если более точно, от образа к образу.
Как программист читает код
То же самое происходит, когда мы работаем с кодом. Мы открываем страницу, изучаем ее, декомпозируем на блоки, идентифицируем разные части – легко отделяем свойства от функций, уровни изоляции методов и свойств, находим константы и так далее. Мы идентифицируем все это по блокам, и поэтому важным аспектом стилизации кода является приведение всего кода к одинаковому виду. Это ключевой фактор, который характеризует читабельность кода.
Почему это важно? Потому что большую часть своего рабочего времени программист читает код. Какой-то прямой корреляции не обнаружено, по большей части это зависит от квалификации, языка (например, Python построен на отступах, и неправильно структурированный код просто не будет работать), качества кода и т.д. Но от 50% времени уходит на чтение своего и чужого кода. Если код сложный, то показатель может достигать 75%, а если код совсем плох, то 95% времени может уходить на чтение и попытку понять, куда нужно добавить одну строчку, чтобы поправить какой-то недочет. А теперь вопрос. Что вы сделаете, если увидите, что ваш код тратит 75% времени на чтение диска или на выделение памяти двусвязным спискам? Программист постарается оптимизировать этот процесс, попробует поменять алгоритм, применить более эффективную структуру хранения и т.д. Соответственно, когда потраченное время стало критичным, я начал инспектировать этот процесс. И можно было бы сказать мол, ну это же мозг, он значительно мощнее любого компьютера и может хранить около петабайта данных. Но, в процессе разработки своего ментального фреймворка по работе с кодом (скрытый процесс формирования привычек чтения кода), я набрел на исследования, в которых датчики следили за движениями глаз начинающего и опытного программистов. Выглядит все это вот так:
Начинающий
Обратите внимание, чем занимается опытный программист. Он выделяет блоки кода, декомпозирует их и читает поблочно, выделяя ключевые части и анализируя их работу. Начинающий же мечется построчно, просто пытается понять, что тут вообще происходит. Львиная доля времени уходит на то, чтобы сложить общую картину и чтение кода происходит с постоянным перекрестным инспектированием.
Видео довольно старое, от 2012 года, и запись была направлена на исследование процессов мозга программиста. Чуть подробнее можно почитать тут и тут.
Вот сейчас самое время вернуться к описанию работы перцептронов. Это наглядная демонстрация работы обученной и не обученной нейронной сети. Исходя из своей базы знаний опытный программист идет по коду подобно интерпретатору, часто даже не осознавая это. Можно подойти к решению этой проблемы также, как мы подходим к проблемам обучения нейронных сетей.
Есть 2 способа ускорить чтение кода:
Количество настройщиков пианино
Представьте, что команда из 5 человек пишет, как хочет, во все модули и компоненты системы, постоянно получая пересекающиеся задания, корректируя код друг друга. Какое возможное количество всех вариантов написания условия в if, если учесть, что каждый пишет по своему? 5. А сколько у нас допустимых блоков? Все конструкции, вызовы одноаргументных и множественноаргументых функций, неймспейсов, классов, трейтов, интерфейсов, позиционирование блоков, статики, зоны видимости и т.д. Это при условии, что каждый использует только 1 стиль написания, который отличается от стилей всех остальных. А если человек 10? А 50? Понятно, что с возрастанием количества человек будет снижаться дисперсия из-за ограниченного количества способов написать один и тот же блок. И это первый уровень, в который мы не вкладываем одну из основных проблем программирования — нейминг переменных. Эффект мультипликатора и всех возможных комбинаций даже не учтен. Накиньте сверху стилистику разделения, отступы на пробелах и табуляции, любовь к if лапше и т.д. и т.п. А еще постоянно поступают новые специалисты и уходят старые. На выходе вы получаете огромный нечитаемый код, к которому невозможно привыкнуть и невозможно выработать хорошо обученную нейронную сеть у программистов в компании.
Наш мозг ленив донельзя
Еще один интересный эффект работы нашего центрального процессора в черепной коробке заключается в крайне негативном восприятии новой информации. Наш мозг ленив донельзя. С массой около 1,5—2% от общей массы тела, мозг потребляет 25% всей энергии организма. Одной из самых ресурсоемких операция для мозга была, есть и остается концентрация внимания. 20-25 минут можно удерживать максимальную концентрацию (привет техника Pomodoro), и за это время мозг сожрет столько глюкозы, сколько он сожрал бы за целый день субъективного покоя. Обработка новых данных это крайне ресурсоемкий процесс. А одна из главных целей мозга — эти самые ресурсы экономить. Это связано с работой нашей ментальной модели. Своеобразный психологический блокер. Выглядит это примерно так. Вы начинаете учить что-то новое. Что-то новое сложно даётся и из-за отсутствия ощутимой динамики прогресса у Вас начинает снижаться самооценка из-за витающей бэкграундом мысли “I’m stupid!”. Наша психика устроена таким образом, что от самооценки зависит всё мироощущение, а от мироощущения, в свою очередь, зависит наш успех в социуме. И для того, чтобы не ломать базовые социальные лифты на адаптационных зависимостях, наш мозг начинает сопротивляться занятиям, снижающим самооценку. Как следствие, вам хочется посмотреть сериальчик, почитать хабр, пойти выпить кофе, посидеть в соц. сетях и т.д. Что угодно, лишь бы не учить ту самую теорию поля Ландау. Или фиксить трудновоспроизводимый баг. Или… читать некачественный код, в котором трудно разобраться. Отличный пример того, как мозг себя ведет по ограничению в этой области — люди лет 70-80, которые в упор не желают осваивать смартфон или 2 кнопки на роботе-пылесосе. Ресурсы на исходе. Мозг отчаянно блокирует процесс обучения и действует по накатанной. Этих ресурсов очень много, пока вы молоды. С течением времени и взрослением их становится всё меньше и меньше. Работает вполне линейно. Благо это компенсируется возрастающей мощностью наших нейройнных сетей. Если мы не говорим о прямой целенаправленной деградации, конечно.
Немного стереотипов
Распространенное заблуждение, которое вы могли слышать «Да ну, я профи, я могу читать любой код. Я быстро и круто пишу, решая проблемы компании. И не важно, как выглядит мой код, если он решает проблему. Остальные просто не могут быстро разобраться, у меня с этим проблем нет.». Если в вашем окружении есть такой кодер, можете сказать ему: «Чувак, у меня для тебя плохие новости. Ты афектишь всю команду, и такой подход является причиной, почему остальные пишут медленнее, когда супер эффективный программист быстро форсит код».
Суперэффективный программист, который пишет без оформления и стандартизации, на самом деле суперэффективен в 2-х вещах:
Зачем нужен code style
Хоть это уже и должно быть очевидно, но нужно как-то подчеркнуть основные моменты.
Code style:
1. Обеспечивает линейное развитие проекта и не влияет на объем кодовой базы. Если вы обеспечили историческое написание понятного кода, то, сколько бы не приходило и не уходило разработчиков, вы всегда имеете равное качество кода, что позволяет проекту динамично расти вне зависимости от его объема.
2. Значительно ускоряет процесс адаптации новых программистов. Если ваш код написан понятно, новый специалист очень быстро обучит свою нейросеть на определение блоков и начнет приносить пользу. Есть такое понятие, как точка самоокупаемости сотрудника. Это точка, с которой сотрудник начинает приносить только пользу. А если код написан понятно, новым сотрудникам не нужно разбираться в бизнес-логике, ему достаточно научится читать ваш код. И чем быстрее он это сделает, тем быстрее перестанет задавать тонны вопросов остальным специалистам, отнимая у них время. А время специалистов, которые прошли точку самоокупаемости, значительно дороже для команды и компании с точки зрения потенциальной ценности приносимой продукту.
3. Убирает зависимость от частностей. Не нужно будет постоянно спотыкаться о чью-то оригинальность и специфическое оформление.
4. Минимизирует эффект ментального блокера при изучении нового кода. Ваш мозг меньше сопротивляется, т.к. не нужно вникать в чужую стилистику. Ментальных ресурсов на чтение понятного кода нужно намного меньше.
5. Минимизирует репутационные потери. Очень скоро, после прибытия в новую компанию, программист начнет делиться впечатлениями с бывшими коллегами и друзьями. И он либо скажет, что тут все круто, либо выделит негативные моменты в работе с кодом. В каком-то смысле тут получается HR-бонус: если вы хотите, чтобы с вами работали крутые программисты, делайте хороший проект. Хоть это не всегда важно, и в ряде компаний на качество кода не смотрят в принципе, а смотрят лишь на доставку фич до прода, это приятный бонус. Не секрет, что частой причиной ухода становится усталость от постоянного перепиливания некачественной кодовой базы.
6. Формирует и воспитывает культуру разработки. Задача программиста лежит на более низком уровне, чем будущее всей компании, но важно донести понимание, что понятность и читаемость кода сейчас влияет на динамику дальнейшей разработки. Если код трудночитаем и не стандартизирован, с болью и страданиями поддается рефакторингу и масштабированию, то с ростом кодовой базы проекта, будет падать скорость разработки. Чем больше некачественного кода, тем сложнее писать новый, тем медленнее развивается продукт, тем сложнее компании наращивать обороты и тем сложнее ей платить вам больше денюжек, потому что много денюжек уходит на то, чтобы обеспечивать жизненный цикл проекта все новыми и новыми сотрудниками, который основное время онбоардинга тратят не на то, чтобы приносить пользу компании, а на классификацию наркотиков, под которыми этот код был написан.
Идеальный код
Все мы понимаем, что его не существует. С точки зрения каноничного code style — это понятие об оформлении кода. И всё бы хорошо, если бы это было правдой. В разработке на длинной дистанции code style более емкое понятие, которое включает в себя принципы разработки. Разбиение кода на логически изолированные блоки в классах или файлах также относится к оформлению. Нейминг, уровни изоляции, наследование. Все это инструменты не только взаимодействия, но и оформления вашего сложного механизма, где каждый кирпичик играет свою роль.
Концепции меняются от языка к языку. Частности выходят на передний план. Но фундамент остается неизменным. Качественный код определяется всего двумя критериями:
Обезличенный код
То идеальное состояние, к которому нужно прийти в этом процессе, называется обезличенным кодом. Я уверен, что многие из вас, открыв рабочий проект и случайный компонент, могут навскидку сказать, кто из коллег это писал. У каждого часто присутствует стилистика. Кто-то любит лапшу из if, кто-то по поводу и без сует лямбды, кто-то любит сокращать переменные так, чтобы сэкономить один символ. В обезличенном коде вы этого сделать не сможете. В идеальном обезличенном коде невозможно определить автора. И этот тот случай, когда вы пришли к финальной точке своего codestyle.
Читабельность на уровне книги
Вспомним 2 главные проблемы программирования? Инвалидация кеша и нейминг переменных. Обойдём стороной тёмное прошлое процессов кеширования и перейдем сразу к нашей боли. Нейминг переменных, классов, объектов, файлов, методов, констант и так далее. Эта проблема имеет 2 крайности. Слишком краткие названия и слишком длинные. Здравый смысл подсказывает, что логика где-то рядом, рядом с серединой. Тут к нам в дверь постучатся суперэффективные программисты и расскажут, что им всё равно. Но зачем нам теоретизировать об этом? Расскажите мне что делает это код?
Второй код читается напрямую и легко. Не нужно особо разбираться в бизнес логике, чтобы понять функциональную нагрузку при таком нейминге. В этом примере мы просто берем весь репозиторий, потом используем builder, чтобы создать коллекцию, потом применяем фильтр. Не нужно даже вникать внутрь кода, чтобы понять, что происходит. Как чтение книги по заголовкам. Но нейминг это еще не всё.
Паттерны проектирования
О паттернах проектирования вас спрашивают чуть ли не на каждом собеседовании. Их публичная цель — повторяемое архитектурное решение. Их побочный эффект — предсказуемость и системность. Тот момент, когда вы переходите на архитектуру, построенную на паттернах проектирования, вы формируете довольно предсказуемую систему. Т.е. исходя из названия вы легко понимаете назначение класса или объекта. Что делает паттерн Repository? Это представление хранилища с методами получения данных. Что делает паттерн Builder? Собирает сложный объект или структуру. И так по всем фронтам.
Существует такой паттерн как Command. Что с ним можно сделать? Конечно, только execute! Вам не нужно изучать, что же в нем внутри. Понятно, что его можно выполнить. Шаблоны проектирования помогают понять, как устроен ваш проект. Если вы написали все хорошо, то не будете задаваться вопросом: «Что у меня лежит в этих директориях?». По названиям вы легко определите, что и где находится.
Скажем так. Все решения на паттернах проектирования были сформированы, неся в своей основе боль разработчика по той или иной проблеме. Эта боль уже была кем-то пережита, оформлена и получила свое решение в виде одной из существующих архитектурных моделей. Более того, всё это было сформировано поверх небезызвестного SOLID.
SOLID
SOLID — акроним из пяти принципов объектно-ориентированного программирования. Заметьте: 5 принципов. Объектно-ориентированного. Программирования. Это не практика. Это не рекомендация. Это не желание какого-то старого программиста поучить молодежь. И много где вы сможете услышать, что SOLID — это принципы. Но если вы посмотрите на манифест SOLID, в котором были описаны 6 признаков плохого проекта, то обнаружите, что SOLID — это не просто принципы. Это условия, при соблюдении которых ваш проект будет обладать гибкостью, расширяемостью и предсказуемым для разработчика поведением. И несоблюдение любого из принципов — это нарушение условий контракта с кодовой базой при котором вы потеряете одно из качеств. Будь то простота восприятия, гибкость, или зависимость на абстракциях: чтобы вы не потеряли, это начало формирования проекта или компонента, который вы будете переписывать. С нуля. Потому что правильно сделать в получившейся реализации гораздо сложнее, чем быстро внести очередные некорректные вкрапления.
Сколько вы видели переписываний проектов? В скольких таких участвовали сами? Не один и не два. В каждой компании вы найдете компонент или целую систему, которая была спроектирована без культуры разработки. Без хорошего code style, без паттернов проектирования, без учета условий SOLID. Отделы разработки каждый день занимаются переписыванием кода. Двойной работой. Зачастую переписывая в такие же трудночитаемые компоненты. И единственный плюс таких переписываний — знакомство специалиста с бизнес-логикой. Т.е. вы переписали код, думаете, что разбираетесь, но вы разбираетесь не потому, что он стал проще, легче, лучше оформлен. В большинстве случаев в нем теперь разбираются просто потому, что сами же его и переписали.
Из этого стоит вынести, что code style это форма социального контракта внутри вашего community в компании. Вы договариваетесь о том, как писать код, с учетом специфики бизнеса, самого кода, архитектуры и планов по изменению кодовой базы. Эта договоренность означает, что соблюдают ее все. Командная работа подразумевает не столько работу вместе, сколько работу в интересах команды. Это не коворкинг, это общая цель к которой идут все. Как следствие, одной из целей обозначается чистота кода как инструмент дальнейшего развития.
Какой выбрать code style? Не важно! Это не обсуждение вкусовщины. Мы же обучаем нейронную сеть, а значит не имеет значения что именно будет в тренировочном сете. Важно, чтобы это были одинаковые блоки. А как они будут выглядеть значения не имеет. Но лучше взять что-то из open-source based стилей. Просто исходя из того, что PSR знает большее количество людей, нежели какой-то свой кастомный. Не говоря уже о крайне распространенном symfony2 code style, который фактически является улучшением и расширением PSR. Это, разумеется, про PHP. В них встроена качественная блочная модель, которая легко читается, легко дополняется и легко поддерживается.
К чему всё это?
Вам, вероятно, хочется узнать к чему это приведет? Я приведу пример с одного из предыдущих мест работы — там получился чистый эксперимент, учитывая, что вопросы CodeStyle не волновали команду до того, как я поднял этот вопрос. Когда я пришел к команде и сказал, что с завтрашнего дня в вашем PHPStorm заведется такой забавный зверь, как phpcs и codestyle протокол — все немного приуныли. Не в моих правилах заниматься нововведениями через репрессии, я попытался донести это через демонстрацию той кучи исследований по распознаванию образов программистом. И все равно поддержка нашлась только у пары человек, которые, как и я, сильно страдали от чтения некачественного кода.
Я пожал плечами и начал писать чистые, хорошо спроектированные (субъективно), изолированные компоненты. Я ведь могу ошибаться, верно? Конечно могу. А потом стал раздавать одним и тем же людям задачи идентичной сложности в новые чистые компоненты и в старые. Постепенно, аккуратно собирая статистику. Спустя 2 месяца я поднял свою табличку в Google Sheets и показал ее команде. На чистом коде эффективность программистов оказалась на 23% выше. Поразмыслив, что 7 человек это не репрезентативно, я продолжил эту практику довольно тихо в параллельном проекте, где работало около 20 фриланс программистов. Результаты оказались несколько хуже. Но да, небольшой состав программистов из более чем 20 человек писал довольно чистый и хорошо спроектированный код. И поверх их кода идентичные задачи другими решались на 21% быстрее. Хотел двинуться дальше, но этого было достаточно, чтобы получить поддержку со стороны команды.
Медленно, но уверенно, мы очищали рабочий проект от плохого дизайна, и в один момент пришли к состоянию, когда 90% кода было выполнено по всем канонам разработки, которые мы определили. К чему это привело? Мы взяли очередного Middle PHP Developer в команду. И его onboarding прошел за месяц, вместо обычных 3-х. А потом еще один такой же… Комплексная бизнес-логика и асинхронное взаимодействие всегда сложно даются. Но не в этом случае. Наш onboarding приобрел характер быстрого обучения бизнес-логике, а не классификации наркотиков, под которыми написан каждый кусок кода. Мы пришли к состоянию, когда достаточно всего 1-го месяца перед выдачей большой и серьезной задачи даже Junior PHP Developer. Коммуникации в стиле «как это работает» были сведены к минимуму. И эта была действительно success story.
Вот так, просто не нарушая правила, которые были написаны задолго до сегодняшнего дня, нам удалось на ровном месте увеличить производительность команд почти на 25%, а тайминг onboarding’а уронить на ⅔. При этом совершенно исключено появление «грязного кода» внутри чистого, потому что никто не позволит вносить непонятно что в отлаженную и работающую систему. А если качество кода изначально низкое, никто не заметит появления новых никуда не годных фрагментов. К тому же сегодня есть достаточно инструментов, которые позволяют следить за качеством и чистотой кода в автоматическом режиме, например, таким плагином phpstorm как Sonar Light.
Во многих компаниях некачественный код — это причина, по которой нужно держать огромный штат Senior разработчиков, основная ценность которых заключается в том, что они знают проект и могут разобраться в любой каше. Вдумайтесь, ресурсы высококлассных специалистов используются для борьбы с последствиями отсутствия культуры разработки, а не для реализации технически сложных систем. Для решения этой проблемы дополнительные деньги уходят на огромный штат Senior QA Engineer со всеми вытекающими дополнительными расходами.
Мне иногда не верят, что эффективность может быть повышена на 21-27%. Окей, предположим, что у нас получился какой-то невероятный результат. Но если даже предположить, что экономия составляет 5%, то при реальном рабочем времени в 5 часов в день (исключая перекусы, перекуры и прочее), то для команды из 5 человек будет сэкономлено 69 минут в день. Простым умножением понимаем, что получается 14 840 минут в год – а это 40 человеко/дней. Почему бы не потратить один из них на установку phpcs и phpstorm? Я уже не говорю о том, каковы будут результаты при оптимизации работы 50 разработчиков.