Предыдущая статья infostart.ru/1c/articles/863471
Предисловие
В данной статье, я попытаюсь изложить опыт и практикуемые подходы, призванные сделать процесс написания и особенно сопровождения программ менее болезненным.
В обзоре сознательно исключены проблемы, полностью устраняемые автоматическими средствами проверки кода. Например, при рассмотрении сложности кода, сознательно исключена цикломатическая сложность, как покрываемая средствами автоматической проверки и ими же востребованная.
Первая часть статьи будет посвящена проблемам, ухудшающим качество кода и способам их преодоления. Вторая часть будет резюмировать первую часть и содержать набор рекомендаций по написанию кода.
1 Критерии оценки качества кода
К качеству кода вполне применима универсальная система оценки качества программы, описанная в первой статье, но, чтобы облегчить восприятие, качество кода будет рассмотрено с точки зрения проблематики непосредственно кода. Будут описаны три основные проблемы, влияющие на качество кода.
1.1 Избыточность
Для частных проявлений данной проблемы уже есть устоявшийся термин – индусский код. Причины её возникновения могут быть различны, но точки воздействия на качество могут быть легко описаны. Это проблемы с производительностью, снижение гибкости и усложнение сопровождаемости.
Влияние на быстродействие программы, как наиболее заметное, может быть отловлено при нагрузочном тестировании, если тестовые нагрузки правильно спланированы и смогут воспроизвести рабочие ситуации достаточно правдоподобно. Профилирование в продуктовой базе избавлено от недостатков тестового стенда, но в свою очередь может значительно снизить производительность и может потребовать растянутого по времени тестирования.
Влияние же на гибкость и сопровождаемость автоматической оценке поддаётся с трудом и лишь в наиболее очевидных случаях.
1.2 Монолитность
Под монолитностью кода здесь понимается неделимость и целостность отдельных фрагментов кода – функций. Монолит не является чем-то очевидно плохим и требующим немедленной переработки, но подобно скале он устойчив к попыткам доработок и требует или коренной перестройки или использования специализированных приёмов и оборудования. Чем более крупный кусок кода обладает подобным качеством, тем больше риск снижения гибкости программы в затрагиваемой области и тем более трудозатратным будет даже банальный рефакторинг – изменение структуры, без изменения функциональности.
1.3 Сложность восприятия (понятность/непонятность)
Для данного класса проблем используется термин когнитивная сложность - то есть степень сложности понимания рассматриваемого участка кода. Но в связи с наличием в русском числе достаточного числа выразительных синонимов, здесь и в иных случаях, я буду пользоваться ими если это оправдано.
В современных высокоуровневых языках программирования, вопрос о том, как писать код кажется неуместным. Гибкость и выразительность синтаксиса позволяет писать алгоритмы любой сложности. Проблема заключается в понятности написанного. И если за понятность машине отвечает целый комплекс программных и административных средств, то понятность для человека, зачастую остаётся на совести разработчика. Очередная сборка, пройдя через горнило тестирования, приобретает минимально необходимые свойства, обеспечивающие работоспособность программы - понятность и целостность для компьютера. Понятность для человека в значительном числе известных мне случаев не рассматривается, или имеет наименьший приоритет и обеспечивается по остаточному принципу. При этом степень понятности кода напрямую влияет на стоимость сопровождения, увеличивая время на его чтение и осмысление. Но так как рассчитать «в точных цифрах» финансовые потери для каждого случая можно лишь путем проведения масштабных экспериментов, стоимость которых превышает сумму возможного перерасхода, то оценка потерь может производиться лишь с использованием аналогий с другими случаями, в том числе не только из области разработки ПО, что в свою очередь снижает достоверность такого анализа в глазах людей отвечающих за распределение ресурсов.
2 Причины проблем
- Недостаточная образованность. Отсутствие фундаментальных и специальных знаний в области разработки программного обеспечения являются наиболее распространенными причинами плохого кода.
- Психоэмоциональные особенности. Все мы, даже самые опытные разработчики являемся живыми людьми. Различные эмоциональные состояния и психологические особенности оказывают непосредственное влияние на наше мышление.
- Недостатки организации. Будучи плохо организованной, даже звёздная команда признанных специалистов будет уступать хорошо организованной команде средних специалистов. Метафора про львов возглавляемых бараном и баранов возглавляемых львом работает в любой области требующей организации.
Проблемы, вызываемые недостатком знаний, в большинстве случаев, наиболее просты в устранении, ведь они требуют всего лишь обучения по скорее всего имеющимся примерам/шаблонам/книгам/курсам. Психологические и организационные причины, напротив, создают условия для возникновения действительно сложных проблем, решение которых может потребовать усилий всего коллектива.
2.1 Пробелы в образовании
Под образованностью здесь понимается совокупность представлений человека о различных аспектах человеческой деятельности, включая не только прикладные навыки класса «как делать», но и теоретические знания класса «почему надо делать именно так».
В данном разделе не будут рассматриваться простые случаи, когда человек просто не знает какую-то библиотеку, паттерн или язык программирования. Такие проблемы решаются легко и существует множество учебных материалов. Но мне нередко встречались люди, чьи проблемы решить было непросто, так как они далеко выходили за пределы обычного обучения специалиста.
Диагностика сложных проблем
Есть простой и действенный способ диагностики ряда серьезных проблем с познавательной деятельностью программистов, который я давно применяю в программах обучения.
Для тестирования необходимо подготовить задание, требующее написать некий алгоритм. Он не должен быть очень сложен и не должен занимать более одного экрана. Задание желательно дать или устно или схематично в виде рисунков – так, чтобы тестируемый мог легко и однозначно понять суть задания. Порекомендовать не использовать готовые текстовые шаблоны, сделав акцент именно на рекомендации, а не прямом запрете. После того как мы убедимся, что задание понято, то приступаем к испытанию. Необходимо ненавязчиво наблюдать за испытуемым и фиксировать ход выполнения заданий.
1 Испытуемый начинает писать код. Замерить время на выполнение задачи.
2 Попросить написать этот же алгоритм на литературной норме человеческого языка. Описание должно содержать исчерпывающее описание того, что делает данный код. Разрешить «думать вслух». Замерить время на выполнение задачи.
3 Расспросить о возникших затруднениях и впечатлениях, сопоставить ответы и собственные наблюдения.
Сравниваем результаты и ход выполнения задач:
А) Если соотношение затраченного времени более чем 1 к 2, то начисляем 1 балл.
Б) Если испытуемый всё равно использовал шаблоны для генерации готового кода и это объективно повлияло на скорость решения первой задачи так, что ответ на первый вопрос принес один балл, то отнимаем один балл.
В) Если в ходе выполнения второго пункта возникли негативные мысли о глупости и бессмысленности задания «ведь всё компилируется!!!» или «всё понимаю, но не могу описать» - начисляем 1 балл.
Считаем баллы. 0 баллов – всё в порядке. 1 – обратить внимание - проблемы возможны. 2 балла – есть проблемы с пониманием того, что человек пишет.
Набор двух баллов в этом простом тесте означает высокую вероятность проблем с логическим мышлением или проблем с восприятием символьной информации. По моим наблюдениям корни проблем уходят в детство и среднюю школу, что требует дополнительной диагностики и определения корректирующей программы обучения.
Проблемы построения абстракций
Широкое использование абстракций, не связанных с объектами реального мира, является специфической особенностью многих профессий, включая профессию программиста. Двойственность и неоднозначность абстракций уже рассматривалась в одной из предыдущих статей, потому не буду подробно расшифровывать позитивные и негативные стороны использования абстракций, а отсылаю к оригинальной статье рассматривающей их основные свойства.
Как уже неоднократно упоминалось, абстрактное мышление является неотъемлемой частью человеческого мышления. Даже маленьким детям и людям с физическими поражениями мозга, доступны, как минимум, абстракции на примитивном чувственном уровне – различается круглое от квадратного, красное от зеленого и.т.д. Но не стоит забывать, что абстрактное мышление, это не некий генетически заложенный механизм, а вполне себе тренируемый и развиваемый навык. Если на определенных этапах развития человек не получил соответствующих навыков, то все последующие этапы будут фактически провалены. Если данная особенность случилась с ребенком, интегрированным в социум, то скорее всего важнейшие социальные навыки такие как разговорная речь будут развиты и обнаружить проблемы можно будет только при попытке выполнения специфической мыслительной деятельности, свойственной программистам. Построение абстракций, не связанных с чувственным восприятием, будет затруднено или вовсе невозможно.
Опытным путём была выработана методика диагностики и корректирующего обучения. Опирался я в основном на педагогические методики для детей дошкольного и раннего школьного возраста, направленные на развитие абстрактного мышления. Наиболее ответственный момент здесь, это правильно оценить этап развития, на котором произошел сбой и начать именно с него, чтобы не вызвать у обучающегося отторжения ввиду чрезмерной «детскости» задач.
В период корректирующего обучения специалист может выполнять рабочие задачи, но необходимо сопоставлять характер рабочих задач с текущей программой коррекции. В идеальном случае, коррекция может полностью состоять из специально подготовленных рабочих задач.
Даже в самых запущенных случаях, развитие идёт быстро, измеряясь в неделях. Главное условие — это отсутствие физических поражений мозга и наличие у человека мотивации к развитию. То есть здоровый, но недообученный в детстве человек, регулярно решая практические задания, сможет прокачать свои абстрактные навыки за сравнительно короткий период времени.
2.2 Психоэмоциональные причины проблем с кодом
Состояние потока
Само явление является слишком сложным и многогранным и для полного разбора требует отдельного исследования. Для целей текущей статьи я очень кратко обрисую основные аспекты этого явления для общего понимания, и ключевые признаки для диагностики.
Вот, что пишет о потоке Википедия со ссылкой на авторитетный источник:
Поток, потоковое состояние, переживание потока (англ. flow, лат. influunt), — психическое состояние, в котором человек полностью включён в то, чем он занимается, что характеризуется деятельным сосредоточением, полным вовлечением в процесс деятельности… У исследуемых в потоковом состоянии повышаются показатели усваиваемости информации, активизируется память, способности к анализу информации, наблюдается лёгкая форма беспокойства, в связи с повышенной активностью.
Сделаем скидку на, то, что научный аппарат вики-статьи представлен преимущественно популярной литературой, хоть и написанной профессиональными психологами/психиатрами. Но в любом случае, определение не только довольно туманное, но и вводящее в заблуждение относительно его природы. Внешние признаки и следствия состояния перечислены как имманентные свойства явления, что на мой взгляд является или ошибкой перевода или небрежностью в оригинале. Для собственного употребления, я сформулировал другое определение:
Состояние потока — состояние устойчивого подъёма настроения (гипертемия) с элементами экзальтации, вызванное непрерывным достижением успеха в какой-либо деятельности. Выход из состояния потока происходит либо из-за усталости, либо из-за прерывания серии успехов.
В данном определении, основные свойства потока такие как вовлечение, деятельное сосредоточение, активизация работы мозга и организма в целом, являются лишь производными от исходного состояния, что на мой взгляд, ставит определение данного явления с головы на ноги.
Именно в таком состоянии, наш мозг в автоматическом режиме услужливо выдаёт необходимые ассоциативные связи, ловко жонглируя множеством объектов. Работать в таком состоянии получается легко и быстро, но из-за специфики мышления и слабой совместимости особенностей мышления с его символьным представлением, понятность кода может быть очень слабой.
Но и это не самое главная проблема подобного состояния. Ведь мы пользуемся интуицией постоянно даже без состояния потока и это действительно экономит много времени на принятие решений. В чем же проблема? Проблема заключается в сути состояния потока – гипертемии. Войдя в это состояние, мы не только повышаем эффективность работы интуиции, но и попадаем в ловушку – находясь в состоянии измененного сознания, можно только волевым усилием выйти из него. Попробуйте, например проснуться, когда вам снится интересный сон, или оторваться от любимой книги/фильма в кульминационный момент. Да, это возможно, но потребует усилий и очевидно бросит вас на противоположный полюс эмоционального состояния.
И это тоже не кажется проблемой, если забыть, что интуиция лишь компоновка нашего опыта, и внутренний голос может через серию условно верных тактических решений привести нас к провалу на операционном уровне. Подобные ситуации прекрасно иллюстрирует следующий анекдот:
Ковбой, отстреливаясь, спасается от индейцев. Индейцы окружили его. В его кольте остался только один патрон…
«Это конец», — думает ковбой и прикладывает дуло к виску.
Внутренний голос шепчет: «Это ещё не конец. Убей вождя».
Ковбой прицеливается, стреляет и вождь падает с лошади.
Внутренний голос: «Вот теперь точно — конец».
В обычном состоянии, подобные ошибки внутреннего голоса часто бывают замечены, и мы останавливаемся чтобы «пораскинуть мозгами» - проанализировать ситуацию. В состоянии потока, такая остановка невозможна без явного волевого решения. Мозг просто подставит относительно правильное или вовсе неверное решение, вместо выхода из потока. Таким образом, человек становится заложником потокового состояния, не имея эмоциональных стимулов на решение возникающих проблем в логических построениях. Ведь любая остановка приведет к прерыванию победной серии маленьких, но непрерывных успехов и выходу из комфортного потока.
Таким образом, несмотря на ряд позитивных факторов, состояние потока в процессе написания кода, а именно при трансляции мысленных образов в формальную символьную систему, является преимущественно вредным и однозначно опасным. В такой формулировке я солидаризируюсь с Робертом Мартином предупреждающем в книгах «Чистый код» и «Идеальный программист» об опасности явления и необходимости выхода из «зоны потока». Но признать состояние однозначно вредным мне не позволит ни логика, ни собственный опыт, ни опыт наблюдения за множеством специалистов. Справедливости ради стоит признать, что Р. Мартин во второй упомянутой книге, признал некоторые достоинства зоны потока и допустил их использование во время обучения. Но в контексте данной статьи, где речь идет о работе на результат, а не ради процесса Р. Мартин однозначно предостерегает от состояния потока. Со своей стороны я лишь рекомендую соблюдать осторожность и регламент работы с потоком. Поток подобен огню, может принести пользу, а может убить, в зависимости от того, как с ним обращаться и какие меры предосторожности применять.
В своей практике, я регулярно с пользой и сознательно пользуюсь состоянием потока в тех областях, где он не может нанести вред. Например, поиск решения задачи в условиях неопределенности со множеством входящих неизвестных, может надолго загрузить формальный логический аппарат, тогда как в состоянии потока можно за считанные минуты или даже секунды перебрать несколько вариантов решения. То есть состояние потока используется как бюджетный и более приятный аналог классического мозгового штурма, где группа людей, преимущественно не связанных с предметной областью, генерируют идеи под запись модератора. Впоследствии специально обученные специалисты, разбирающиеся в предметной области, но зашедшие в тупик при решении нестандартной или сложной задачи, анализируют высказанные «в порядке бреда» идеи и зачастую находят решение. И если вы в состоянии выполнять роль модератора, то использование состояние потока для решения инженерных задачи вполне оправдано.
Но используя поток, нельзя забывать, что источником состояния являются эмоции, переключающие ваш мозг в интуитивный режим. И сами эмоциональные состояния, и интуитивное мышление не являются стабильными. Поэтому нельзя закладывать в свои планы, что решение будет принесено потоком к вашим ногам. Бывает, ни интуиция, ни сверхработоспособность не генерируют подходящих идей или дают их слишком много. В этому случае вам придется идти путём формальной логики и математики, вычисляя решение, а не получая его в готовом виде. Это, как правило, потребует больше времени, и если вы после нескольких успехов заложили в свои планы и графики безусловное срабатывание потока, то вас будет ждать горькое разочарование и прочие неприятные последствия, вызванные срывом сроков.
Когнитивные искажения от избытка осведомленности
Казалось бы, знания не могут помешать, но часто они становятся лишними и генерируют помехи. По моим наблюдениям, проблемы подобного класса часто идут рука об руку с проблемой «состояния потока».
«Горе от ума»
Бывает, что слишком высокая абсолютная или относительная квалификация приводит к проблемам и недопониманиям. Проблемы возникают от высокой осведомленности о технологиях, возможностях синтаксиса и недокументированных возможностях. Использование сложных или редких технологий, методов или приёмов программирования настолько хорошо знакомых автору, что ему сложно представить, что это может быть непонятно кому-то другому. Грань здесь тонка, но личная практика наблюдений показывает, что опытные разработчики, пишут более понятно и поясняют неочевидные ходы. Менее опытные специалисты, зачастую усугубляют проблему, становясь жертвой подсознательного желания «показать класс», уподобляя себя лихачу-водителю, отыгрывающему форсажевского Доминика Торетто в плотных потоках городских улиц.
Но даже четко осознавая разницу между собственной квалификацией и объёмом знаний и общими, человек всё равно будет неизбежно подвержен влиянию данного искажения.
В качестве мер преодоления лучше всего использовать комплекс мер, который позволит уменьшить негативные последствия от разницы в уровне подготовки:
поднятие среднего уровня знаний за счет обучения и наставничества/менторства;
соглашения по оформлению кода
соглашения по использованию библиотек и компонентов.
«Многие знания – многие печали»
Так я условно обозначаю явление генерации определенного пула абстрактных и зачастую несвязанных данных, хранимого большей частью в голове разработчика. Здесь под высокой и даже излишней осведомленностью, понимается слишком глубокое погружение в контекст, не важный и не принципиальный для алгоритма. Это временная конструкция неосознанно возникающая при попытке построить единую модель данных и обрабатываемого алгоритма.
Написанный код, в данном случае, является скорее стенограммой потока сознания, чем осмысленным текстом. В крайних случаях является причиной появления нечитаемых или бессмысленных идентификаторов типа «Перем1» … «ПеремN», «списАчеГ» и.т.п. Ирония данного явления в том, что на момент написания программисту абсолютно очевидно, что Перем1 это список товаров, а списАчег это список контрагентов в начале функции и таблица платежей в конце. Более того, он даже в уме не оперирует терминами, отражающими содержимое, а пользуется обезличенными именами, легко и четко понимаемыми исходя из контекста употребления. Но спустя некоторое время, автор подобного кода неизбежно утрачивает контекст, и собственноручно написанный код, становится древними иероглифами даже для него.
Выход во всех подобных случаях, есть переход от потокового воспроизведения мыслительного процесса к сознательному изложению сформулированной мысли. Хорошо помогает довольно простой приём – во время написания кода, представлять, что вы не просто пишете код, а заочно объясняете кому-то менее квалифицированному и осведомленному, как именно работает данный код и почему вы применяете те или иные подходы, если эти подходы отличаются от стандартных и общеупотребимых.
Шаблонное мышление
Указанное явление может быть причиной любой из трёх основных проблем как по отдельности, так и в любом их сочетании. Термин «шаблонное мышление» в русском языке уже давно приобрел черты устойчивого словосочетания с ярко выраженной отрицательной коннотацией, что не вполне справедливо. Поэтому считаю необходимым уточнить суть данного явления, прежде чем будет рассмотрена его роль в снижении качества кода. Шаблонное мышление само по себе не является чем-то плохим, так как это естественный для человеческого мозга приём. Это есть частный пример применения абстракций в ходе построения сложных логических моделей.
Устоявшийся во многих языках термин подразумевает бездумное шаблонное мышление – то есть применение набора шаблонов на уровне интуиции и рефлексов, а не на основе сознательного рассуждения.
Код, написанный в худших традициях данного подхода, будет представлять собой набор шаблонов решения тех или иных ситуаций, подбираемых подсознанием автоматически. Читать такой код может быть сложно, так как он не являет собой цельное повествование, а больше похож на результат плохой игры в тетрис, где игрок, интуитивно ставя фигуры в «подходящие» выступы и углубления поднимает высоту своего здания на критическую высоту.
Используйте шаблоны, только понимая, что лежит «под капотом». Конечно, чем глубже понимание процессов проходящих под поверхностью абстракций, тем лучше, но даже общего осознания вполне достаточно. Ведь главная проблема именно в бездумном подборе подходящих фрагментов кода.
Варианты потенциально опасных сценариев:
- «Попробую нажать эту кнопку, в прошлый раз это помогло».
- «Не знаю почему, но мне кажется, что это должно быть здесь».
Пример правильного сценария:
- «Для выполнения заданных операций требуется набор действий, который является частью шаблона. Также, чтобы не тратить время на набор текста, я подвесил этот шаблон на хоткей».
Инстинкты доставшиеся от предков
Импринтинг
Древний и весьма полезный приём, выработанный миллионы лет назад, вероятно задолго до появления не только первых млекопитающих, но и до выхода наших предков на сушу. По крайней мере исследователи находят признаки импринтинга у рыб и насекомых. Дословно переводится как запечатление – отпечаток чего-либо в эмоциональной памяти. Так детеныши запоминают родителей, родную речь, березки, речку, окушков в пруду. Впервые познакомившись с первой в жизни средой разработки, методикой или идеей – человек эмоциональное привязывается к ней. При отсутствии самоконтроля приводит к утрате критического восприятия адекватности используемых инструментов решаемым задачам.
Нечистоплотность
К сожалению, данное свойство есть общий видовой признак, если не для всех, то для большинства приматов. Миллионы лет эволюции на деревьях на инстинктивном уровне отучили приматов беспокоиться о чистоте территории. Ветки, клочки шерсти, остатки еды, отходы жизнедеятельности и не слишком приятные сородичи утилизировались простым и незамысловатым образом - с высоты древесных ветвей. Вошедшая в лексику «нечистоплотность» свиней, в большей степени относится к самим людям и их родственникам. Например, наблюдая за поросятами, отнятыми от матери сразу после рождения, я с удивлением заметил, что они сразу же разметили территорию тремя максимально удаленными друг от друга точками: место сна, место еды, место справления нужды; и никогда никто из них эту разметку не нарушал. Многолетние наблюдения как за детенышами человека, так и за взрослыми людьми – убеждает во мнении, что современная относительная чистоплотность — это приобретенный культурный навык, прямо противоречащий инстинктам.
В работе, данная группа инстинктов, проявляется в двух основных проявлениях. Я в шутку называю их «накодить прямо там, где застала нужда» и «парадокс чистого места». Про ситуативные правки там, где править не только не нужно, но и порою категорически нельзя, можно не расписывать подробно. Каждый встречал и каждый так делал, когда никто не видит или «я потом уберу».
Парадоксом чистого места я обозначаю конфликт между безусловными рефлексами и приобретёнными культурными рефлексами. Многие из вас замечали, что если где-то есть чистое место, то даже не очень культурные в быту люди, будут там максимально осторожны и аккуратны. Ровно до первого окурка, брошенного мимо урны. То есть инстинкты подавлены у подавляющего большинства людей и культурные рефлексы успешно работают, если есть позитивное подкрепление – чистота.
Отсюда и простые методы борьбы через соблюдение правила туриста – оставляйте место после себя чище чем оно было до вас, ну или по крайней мере не грязнее.
3.3 Недостатки организации, влияющие на качество кода
Бессистемная разработка
Как при написании кода с нуля, так и при внесении в него изменений, отсутствие планирования пагубно сказывается на качестве кода. Даже новый код, написанный без предварительного плана, уже может быть избыточным и сложным для восприятия. Если же подобный код регулярно, но всё так же бессистемно модифицируется, то рано или поздно все существующие проблемы будут усугублены и сцементированы множеством перекрестных зависимостей.
Для преодоления подобной проблемы есть уже давно известная человечеству методика – предварительное планирование. При этом в зависимости от объёма предстоящей работы, объём планирования и затрачиваемое на него время также должно масштабироваться.
Чтобы начать работать по-новому, вам потребуется приобрести довольно несложную привычку. Всякий раз, когда вам нужно создать новую или доработать существующую функцию и тем более если речь идет о классе или подсистеме, вам потребуется сделать паузу и письменно ответить на два довольно простых вопроса:
1. Что ожидается от работы планируемого к написанию кода. То есть какие операции и с какими данными должны быть произведены, чтобы код считался работоспособным?
2. Что нужно сделать для достижения требуемых результатов?
Ответив на первый вопрос, вы фактически создаёте спецификацию на будущий алгоритм. Как несложно предположить, помимо прямой пользы от планирования, вы сможете использовать созданное описание для внутренней документации, что в свою очередь значительно облегчит дальнейшее сопровождение кода.
Ответив на второй вопрос, вы сформируете пошаговый план работ. Пункты плана в зависимости от степени детализации превратятся или в структурные элементы алгоритма, или в вызовы других функций.
Переработки
Вечерние, ночные, субботние и воскресные посиделки на работе известные как авралы или кранчи могут быть как единовременным форс-мажорным событием, так и систематической практикой. В случае, если вам постоянно приходится работать более 40 часов в неделю, то необходимо пересмотреть подходы в работе.
Во всех известных мне случаях, практика систематических переработок имеет два питающих источника:
Самообман, когда кажется, что, отработав 10-12 часов вместо 8, вы сможете сделать на 25-50% больше работы.
Плохая организация труда, когда из-за низкой продуктивности или плохого планирования приходится перерабатывать, чтобы успеть сделать запланированное в срок.
Самый главный и непосредственный минус прямо следующий из практики переработок это – усталость. Усталость и моральная, и физическая. Уставший специалист совершает больше ошибок и более склонен к принятию первых пришедших в голову решений, так как из-за усталости, критический аппарат страдает одним из первых. В личной практике неоднократно проводил эксперименты, подтверждающие данное мнение. Систематическая переработка, в среднем, менее продуктивна чем работа по регламентированному календарю. В ходе экспериментов неизбежно подтверждалось, что на начальном этапе, может произойти просадка из-за необходимости перестройки рабочих процессов, ранее «заточенных» на переработки, но в дальнейшем, продуктивность растет и стабилизируется на более высоком уровне чем до изменений. При этом повышается не только фактическая продуктивность, её бывает сложно замерить. Субъективные ретро-перспективные оценки разработчиков, также показывают, что они могут делать больше (или хотя бы столько же) за меньшее время.
Постоянные переработки приводят к изменению в поведении и потребностях. Значительно меньше времени остаётся на общение с близкими людьми, на хобби, самообразование и культурный досуг. А ведь именно разнообразие видов деятельности и социальная активность отличают человека от робота. Тактически, вы можете получить больше денег и признания. Отдавая своё личное время работе, вы в долгосрочной перспективе перестаёте быть тем специалистом и человеком, который нужен работодателю в частности и обществу в целом. Ведь ценность специалиста не только в большом опыте прикладных специальных знаниях, но и в широком межотраслевом кругозоре и жизненном опыте, способности понимать взаимосвязи между событиями, их причин и следствий. В конце концов умение решать рабочие проблемы в течение рабочего дня, не появится, если переработка является нормой.
Отсутствие контроля качества
Независимо от уровня и квалификации специалистов в рабочем коллективе, контроль качества необходим. В идеальных и простейших случаях, контроль будет производиться самими работниками, в других потребуется ввести некоторые регламенты, но отсутствие контроля однозначно приводит к потере качества. Даже опытный человек может ошибиться, даже самый ответственный может в некоторых случаях пойти на компромисс с совестью.
Вопрос контроля качества очень сложный и объёмный чтобы подробно рассмотреть его в рамках данной статьи, поэтому прошу извинить меня за сверхсжатое изложение.
Сформулирую главный принцип организации контроля качества, который нужно глубоко понять: Качество должно обеспечиваться на входе и во время выполнения рабочих операций. Отсутствие проблем при финальном контроле, является целью любой добросовестной системы контроля.
То есть, качество, в первую очередь, это не дамоклов меч ОТК. Качество — это такая организация труда, где ошибки являются досадным исключением, а не обыденным следствием плохой организации. Под организацией труда, здесь понимается и регламент рабочего времени, рассмотренный в разделе о переработках; и система обучения; и соглашения по написанию кода и оформлению документации; и наличие общих принципов и стратегии развития архитектуры всего приложения – всё то, что обеспечивает выпуск качественного кода.
Чрезмерное доверие автоматическим тестам
Программа, контролируемая только автоматическими средствами тестирования, развивается по тем же принципам, что программа, тестов лишенная. Система автоматического тестирования, не подкрепленная человеческим анализом, подобна джипу из старой шутки: «Чем круче джип, тем дальше идти за трактором». Да, средства контроля позволят исключить большую часть ошибок, но те ошибки, что автоматическими средствами не выявляются, накапливаясь и усиливаясь, рано или поздно приведут систему в неподдерживаемое состояние и придется идти пешком за «трактором».
При этом я не критикую сам подход. Наоборот, налаженная система автотестов позволяет разгрузить значительный объем рабочего времени от рутинной работы и освободить время для той работы, которую может сделать только человек.
3 Как писать код
В этом разделе я обобщу описанные выше проблемы и резюмирую их в виде кратких рекомендаций. Итак, товарищ коллега:
Постоянно учись и тренируйся.
Программисты входят в число тех специалистов, уровень которых обеспечен не только фундаментальными знаниями и багажом опыта, но и развитыми прикладными навыками. Здесь программисты подобны бойцу спецназа, который может быть сколь угодно опытным тактиком, уметь владеть всеми известными видами оружия и снаряжения, но без банальной физической подготовки, обеспечиваемой постоянными изнуряющими тренировками, он будет в лучшем случае бесполезен, в худшем случае – вреден для команды. При этом физическая подготовка без специальных знаний абсолютно так же беспомощна.
Не стесняйся писать свою консоль запросов или очередной «универсальный перенумератор». Да, скорее всего это изобретение велосипеда, но без регулярных тренировок ты не достигнешь уровня, когда сможешь привнести что-то новое в сообщество. Пробуй себя в новых областях, решай необычные задачи – и твой навык будет расти.
Пиши так, словно объясняешь
Пиши так, словно объясняешь кому-то, что ты хочешь получить в результате выполнения кода. На сопровождении продукта, на средних и поздних стадиях и в процессе разработки чтение и осмысление кода занимает большую часть времени разработчика. Ясное изложение, помимо пользы для коллектива в целом, принесет пользу и тебе лично. Думая над формулировками, ты будешь с удивлением замечать логические ошибки в алгоритме, абсурдные имена переменных и бессмысленные комментарии. Также не забывай, что после утраты (забывания) контекста, ты будешь вынужден повторно изучать написанный код наравне с теми, кто его видит впервые.
Пиши просто и очевидно.
Тем более если ты начинающий и не слишком опытный специалист. Если твои намерения в коде будут изложена ясно, то и поиск логических ошибок будет значительно легче. Не бойся допускать ошибки – это неизбежно, бойся того, что твои ошибки будет сложно заметить. Если твоя мысль будет прозрачна и очевидна читателю, то и логические ошибки будут замечаться как интуитивно ощутимые «нестроения» в стройном изложении.
Не пиши в состоянии душевного волнения.
Если чувствуешь, что настроение отличается от спокойного, то прервись и постарайся прийти в норму. Выработай для себя методы обретения спокойствия. Это может быть и физическая разминка, и короткая прогулка по офису. Если измененное состояние позитивное и устойчивое, то попробуй на время переключиться на вид деятельности, не требующей спокойной сосредоточенности. Проектирование нового класса или таблицы данных, рефакторинг запутанного кода, к которому ранее страшно было подойти – дерзай, и с большей вероятностью чем обычно тебя ждёт успех. По крайней мере, ты сможешь более продуктивно использовать заминку в написании кода.
Планируй свою работу письменно.
Независимо от масштаба предстоящих работ, уделяй время планированию. Если это коротенькая функция, то план может состоять из 1-2 пунктов. Если это новый модуль, то план может состоять из 3-10 или из тех же 1-2 пунктов, но подразумевающих дробление. Не пытайся предусмотреть всё в мельчайших деталях, если в этом нет крайней нужды. Направления и вехи пути вполне справятся со своей задачей, а их создание не займёт много времени. Не бойся менять планы, если они становятся неадекватны стоящим задачам. Это значит, что ты или всего лишь что-то не учёл, или не мог учесть из-за неопределённости вводных данных. Просто вноси изменения в существующий план и продолжай работу.
Отдыхай от работы.
Не стремись сделать всю работу. Во-первых, это невозможно, во-вторых, переутомляясь, ты теряешь продуктивность. Но отдых — это не обязательно лишь диван и телевизор. Ты вполне можешь сменить вид деятельности – сходить на спортивную площадку, погулять с семьёй, сделать пару коммитов в открытый опенсорсный проект или собственную нетленку, прочитать или написать статью, посмотреть исторический ролик или провести собственное расследование. Множество сфер деятельности доступны тебе в личное время. Самое главное при этом – соблюдать суточный баланс и вовремя ложиться спать. Дефицит сна снижает продуктивность намного сильнее и надёжнее, чем какая-нибудь очередная хандра под новым названием, будь то профессиональное выгорание или синдром недостаточно зеленой травы под окном.
Проверяй свою работу.
Если ты работаешь один или нет специально выделенных людей для контроля, то это не повод для отказа от проверок, а скорее показание. В коллективе же организация проверок выполняется проще. В самом доступном варианте – каждый просматривает коммиты остальных. Если этого недостаточно, то можно выделить отдельного человека, который будет внимательно и вдумчиво проводить ревью кода. Ты и сами можешь проверять собственный код. Но желательно это делать после исчезновения эмоциональной привязанности к написанному коду. После некоторой практики, утренняя проверка написанного накануне будет вполне эффективна. Где-то поправится невнятная формулировка, где-то исправится ошибка – и вот твой код уже стал лучше.
Не доверяй роботам
У автоматических тестов другая задача. Автотесты в состоянии надежно выявить ошибки, которые могут помешать работоспособности текущей версии программы, но остальные свойства им почти неподвластны.
4 Заключение
В данном материале, были рассмотрены причины плохого качества кода, средства борьбы с ними и резюмирующие рекомендации по написанию кода.