илл. «О чем размышляют роботы?» — Жан-Пьер Пети
илл. «О чем размышляют роботы?» — Жан-Пьер Пети

Самодостаточность шаблона

Конечно, код пишется в первую очередь для машины, а потом уже для людей. Тем не менее, принимать кого-то нового и постороннего в свою среду, уж тем более ощущать его присутствие – бывает довольно-таки непросто. Например, вот проект, над которым я работаю. Вот тут у меня были функции: getUserHandler, createUserHandler, getUsersListHandler. А вот кто-то создал рядом ещё одну, назвав её loadSettingOfUser – это как это так?

Как ни странно, но нет, я назвал так те функции вовсе не для того, чтобы их назначение было как можно более понятно из названия. И даже не для какой-то абстрактной «красоты» / «чистоты» кода – это понятия субъективные. Я так их назвал ровно с одной целью – чтобы для каждой из них у меня был ответ на вопрос – почему она так называется? И вот этот ответ: а потому что другие называются аналогично. Всё. Остальное — это уже вопросы к шаблону, и они в данном случае второстепенны. Такая политика сформировалась у меня вполне естественным образом – путём долгой возни с самим собой на тему «какое же всё-таки название выбрать будет правильнее».

Задача самого шаблона тоже довольно нехитрая – чтобы его существование было ясно, и лишний раз никому в голову не приходило бы его нарушать – это должно ощущаться чем-то вроде испачканной белой рубашки, выбрасыванию окурка посреди чистого тротуара и т. п. Впрочем, переделать сам шаблон – почему нет, если никто не против, если хватит сил и энтузиазма. И на этом моменте про шаблоны, пожалуй, всё – либо понятно, либо нет: можно обосновывать дальше и дальше, но опыт подсказывает, что это бессмысленно. Человек даже может согласиться со всеми аргументами, но если трёх абзацев не хватило – вероятно, ему не хватит и целой книги на эту тему. Что впрочем вовсе не свидетельствует о его профнепригодности.

«Пишем комментарии»

// Получаем имя пользователя
username := getUserName()

Часто встречал комментарии, написанные подобным образом. Может даже и сам когда-то писал такие – уж наверняка, «шаблоны», все дела. Однако, одумался. И, нет – мы ничего здесь не получаем, получает машина, а человек, пожалуй, пишет код. Нет, ну, можно, конечно, представлять, что вот он – компьютер, а я вместе с ним как некая «мамочка» – и вот, мы что-то там получаем.

 // Получение имени пользователя
 username := getUserName()

Ну, согласитесь, стало же лучше?

Стандартизация глубинная

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

В этом плане мне довольно близка идеология языка Golang. Однако, не смотря на его строгость, в нём тоже есть моменты, когда можно сделать совершенно одно и то же, но разными способами. Пример:

len(val) == 0
// или
val == ""

Круто, когда одна задача – одно решение. Но здесь сам язык вынудил фанатов стандартизации допустить такую ситуацию, ничего не поделаешь — вроде как можно и длину строки получить, а вроде как можно и сверять её с константой. Спойлер: если речь идёт о проверке на пустую строку, то, конечно же второй вариант предпочтительнее – сразу ясно, что val – строка, а не slice или map. В таких ситуациях достаточно определиться один раз и дальше делать аналогично – на этот случай встречаются всяческие сборники рекомендаций и соглашения (наподобие «Go Code Review Comments»).

Чем проще, тем лучше

Это одна из немногих аксиом программирования. Хотя, возможность трактовать слово «проще» на свой лад всё равно остаётся за человеком: проще для восприятия программистом? Проще в абстрактом смысле? Проще для исполнения машиной?

Гляжу очередную вакансию, такс, такс, такс, что тут у нас? Docker, Kubernetes, Helm, Prometheus, Grafana и Kafka… Так, вы что, хвастаетесь? Это звучит примерно как если бы я сказал – «за свою жизнь я переболел триппером, сифилисом, гепатитом, плотно сижу на стимуляторах и имею за плечами судимость» – ну, то есть, нечего стыдиться, окей, допустим. Но только и радоваться тоже нечему. Если пытаться меня заманить подобным списком, подумайте – может что-то всё-таки вы добавили для так, для красного словца, и ещё не поздно вычеркнуть? В идеале – для таких случаев существует некая локальная документация / набор неких ссылок, и новому работнику нет необходимости быть знатоком подобных технологий – он просто разбирается в них на ходу.

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

Я наблюдал разные экосистемы, видел, например, монолитный проект на Golang’е, где не использовались не то что модули, но и вообще никакие менеджеры зависимостей – какой версии библиотеки туда попадали, такой они там и оставались до конца, распространяясь zip-архивом почти на гиг. И это, конечно же, обратная крайность – когда проект варится исключительно в собственном соку.

Комментарии (14)


  1. Naf2000
    05.09.2022 08:12
    +6

    комментарий тут явно не нужен, из оператора присваивания и названия метода видно, что мы делаем.


    1. DvoiNic
      05.09.2022 08:46
      +8

      угу, как писал Д.ВанТассел в своей книге еще 40 лет назад:
      «Комментарии должны содержать дополнительную информацию, а не перефразировать программу.»


      1. dvoeglazyi Автор
        05.09.2022 13:47

        Я согласен – комментарий к той строке действительно не нужен. Только речь не была не о нём, а о его формулировке.

        Но про "перефразировать программу" - тут уж не соглашусь, смотря что она из себя представляет - бывает и такое, когда стоит "перефразировать".


    1. SpiderEkb
      05.09.2022 09:39
      +2

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

      Например, один человек просто взял параграф из ТЗ, перенес его в код в виде комментариев и добавил туда код, который все это реализует.

      А через год совершенно другому человеку сказали "вот в этом месте нужно изменить логику с этого на это" и дали исправленное ТЗ. Он берет код и сразу видит где именно нужно внести изменения. И тратит на это минимум времени.

      И обратная ситуация - один написал не утруждая себя комментированием "потому что и так все понятно", потом уволился, а через год кто-то другой тратит время на понимание а где же именно нужно поменять ту самую пару строчек. Потому что в ТЗ вроде как все просто и понятно, но вот реальный код с тем что в ТЗ написано, напрямую никак не связан.

      Хотя это уже более широкий вопрос - не столько о комментариях, сколько о документированности кода вообще. Очень актуален для "долгоживущих", развивающихся системах со сложной бизнес-логикой, требующих внесения изменений в связи с изменением каких-то внешних условий (изменилось законодательство - поменялся бизнес-процесс - нужно внести изменения в бизнес-логику и поправить код). В таких системах ТЗ является одновременно и документацией по коду и там тоже ведется свой контроль версий, контроль правок и т.п.

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


      1. DvoiNic
        05.09.2022 09:59

        Например, один человек просто взял параграф из ТЗ, перенес его в код в виде комментариев и добавил туда код, который все это реализует.

        Пришло ТЗ по обмену с поставщиками — так я не параграф, а практически все ТЗ имею в коде в виде комментариев. В каждой процедуре, реализующей свой параграф ТЗ — именно этот кусок ТЗ, в описании структуры данных — кусок ТЗ. (до более мелких процедур, конечно, ТЗ не опускаю.) Но там нет «масла маслянного» ака
        // Получение имени пользователя
        username := getUserName().

        Если и будет в ТЗ такое, то будет нечто вроде
        // Получить имя пользователя
        (и вот тут мы уже вставляем реализацию: username := getUserName())
        // Получить его хэш такой-то функцией…
        // вставить полученый хэш в текст запроса…
        просто потому, что в ТЗ говорится что сделать


  1. StanKra
    05.09.2022 11:10

    Конечно, работа по шаблонам - важнейший, а зачастую - единственный способ получения приемлемой производительности труда в любой профессии, в том числе программиста. Собственно, любой язык программирования есть фиксированный набор шаблонов. И задача программиста и заключается в искусстве построения работающей программы на основе выбранного набора шаблонов. Авторская статья в своем основном посыле "проект было легко принять следующим разработчикам" и акцентируется на работе по уже хорошо известным шаблонам. Любой шаг в сторону для следующих разработчиков будет проблемой. В таком случае следует признать, что все, без всякого исключения, программы пишутся не для машины, а для людей. Машинное исполнения в абсолютном большинстве случаев - сильно мешающая неизбежность, когда красиво задуманная и виртуозно написанная программа в самом лучшем случае оказывается наполненной совершенно не предусмотренными коллизиями, сбоями, дырами и прочими неприятностями. Совершенно не случайно не отлаживаемых программ не существует и процесс отладки один из самых трудоемких и тяжелых в интеллектуальном плане, когда приходится так или иначе рушить всю задуманную красоту. Конечно, шаблоны сильно уменьшают количество программных проблем, но совершенно не являются панацеей, гарантирующих их отсутствие. Самодостаточность шаблона заключается исключительно и только в том, что интеллектуальную задумку одного программиста может быть поймет другой программист. Но не более того. Ни для какого процессора никаких шаблонов не существует даже в принципе.


  1. amarao
    05.09.2022 12:06
    +9

    Конечно, код пишется в первую очередь для машины, а потом уже для людей.

    Нет. Код, который пишется для машины, а потом уже для людей хранится в .S файлах и выглядит примерно вот так вот:

    /arch/arc/lib/strcmp.S

    ENTRY_CFI(strcmp)
    	or	r2,r0,r1
    	bmsk_s	r2,r2,1
    	brne	r2,0,.Lcharloop
    	mov_s	r12,0x01010101
    	ror	r5,r12
    .Lwordloop:
    	ld.ab	r2,[r0,4]
    	ld.ab	r3,[r1,4]
    	nop_s
    	sub	r4,r2,r12
    	bic	r4,r4,r2
    	and	r4,r4,r5
    	brne	r4,0,.Lfound0
    	breq	r2,r3,.Lwordloop
    #ifdef	__LITTLE_ENDIAN__
    	xor	r0,r2,r3	; mask for difference
    	sub_s	r1,r0,1
    	bic_s	r0,r0,r1	; mask for least significant difference bit
    	sub	r1,r5,r0
    	xor	r0,r5,r1	; mask for least significant difference byte
    	and_s	r2,r2,r0
    	and_s	r3,r3,r0
    ...

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


    1. dvoeglazyi Автор
      05.09.2022 13:56

      Вот прям с первой строки вы мою статью поражаете... Если "остальной код пишется для людей" - может посоветуете нам заняться "ручной трассировкой"?


      1. amarao
        05.09.2022 14:34
        +5

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

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

        А социальная составляющая заключается в объяснении намерений, условий объяснении терминологии. Потому что когда код пишут или меняют несколько человек, ошибка в этом месте приводит к очень трудно устранимым последствиям. Если один человек не так понял другого человека, это будет отражено в коде, причём в том месте, где второй человек его не видел или не до конца понимает (из-за большой локальной сложности), но это будет оказывать разрушающее (unsound) влияние на взаимодействие кусков кода.

        Так что код пишется для человека. Ещё он должен проходить тесты и что-то делать, но это второстепенно.


      1. DvoiNic
        05.09.2022 16:16

        Из той же книги:
        «Помните: программы читаются людьми.»


  1. Far_Rainbow
    05.09.2022 13:58
    +1

    Комментирую изображение к заметке: а игра "три в ряд" это дополнение, замена или воспроизведение какого природного процесса по мнению робота? Спасибо.


    1. dvoeglazyi Автор
      05.09.2022 14:02

      Отвечу вам заместо робота — это воспроизведение абстрактного, т.е. по сути очень упрощённого природного процесса, будь то уборка мусора, построение гнезда, не так уж важно — везде можно отследить некий феномен "перемещения предметов в нужный порядок".


  1. SaemonZixel
    07.09.2022 02:01

    Круто, хоть кто-то на хабре написал статью как он программирует!) Плюсую.

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

    Табы и фигурные скобки - я тоже так делаю. Но заметил, что иногда выгодно т.е. красивее открывающую фигурную скобку поставить на новой строке. Тогда комментарий к фрагменту кода не надо отбивать пустой строкой сверху. Да и любители чётко придерживаться правильных code-styles начинают менее возмущаться, что тоже плюс.

    А вообще со всем согласен, что Вы написали. Смотрю на вещи так-же. Сколько Вы уже лет программируете, позвольте поинтересоваться?)


    1. dvoeglazyi Автор
      07.09.2022 18:10

      Спасибо. Сколько лет - у меня нет однозначного ответа. Лет 5 этим делом зарабатываю, а так - больше 10.