Игорь Камышев — разработчик веб‑приложений и техлид. Люблю чистый код и работающие продукты. Программирую на TypeScript, иногда на JavaScript или PHP.

Веду каналы в Телеграме: kamyshev.code об архитектуре ПО и софт‑скиллах, Глубокий JavaScript о тонкостях JS и несколько других.

Проекты

Просто спросить
2018‑2019

Сервис «Просто спросить» помогает людям, столкнувшимися с онкологическими заболеваниями. Служба бесплатно подскажет, как организовать качественное лечение.

Спроектировал приложение, руководил разработкой при несдвигаемом дедлайне. Поддерживаю сайт после запуска.

Стек: JS (React, Node.js, TypeScript).

Faster
2018

Faster — аптечный маркетплейс, в котором можно забронировать лекарства в любой аптеке города.

Организовал рефакторинг легаси‑кода и ускорил поиск по лекарствам в 10 раз. Реализовал масштабируемую архитектуру. Перевел фронтенд на TypeScript.

Стек: JS (React, TypeScript), PHP (Yii2).

CRM ФРМСП
2018

CRM Фонда развития малого и среднего предпринимательства позволяет работникам легко обрабатывать обращения, прослеживать их историю и отчитываться перед регулятором.

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

Стек: JS (Vue), PHP (Symfony).

QEEP‑Pro
2017‑2018

Платформа «QEEP‑Pro» объединяет в себе CRM, интернет‑магазин и мобильное приложение. Проект стартовал в 2011, к 2017 оброс значительным количеством легаси.

Поддерживал и развивал сайт и мобильное приложение. Разработал генератор интернет‑магазинов, сделал функциональность почтовых рассылок.

Стек: JS (React, ReactNative, Vue, TypeScript), PHP (Symfony).

Procraft
2017

Procraft — это CRM, с помощью которой самозанятые настраивают рекламу, создают лэндинги для продажи своих услуг и получают аналитику по клиентам.

Занимался модулем статистики. На бэкенде сделал интеграцию с Google Analytics и агрегации полученных данных, сверстал и имплементировал графики для сайта и мобильных приложений.

Стек: JS (React, ReactNative, TypeScript, Relay), Scala (Play, Slick, Sangria), GraphQL.

Опыт

Breadhead
06.2018‑сейчас

Фулстек разработчик, техлид

Сейчас работаю в Breadhead — мы делаем веб‑сервисы, связанные с образованием, e‑commerce и автоматизацией процессов.

Я строю архитектуру новых приложений и оптимизирую легаси‑код, контролирую качество кода. Валидирую запросы бизнеса, превращаю их в задачи и распределяю между разработчиками. Привел все приложения к единому стеку технологий. Ввел практику написания тестов и код-ревью. Автоматизировал интеграцию и доставку, настроил CI/CD. Руковожу командой из 4 разработчиков.

Netology
04.2018‑сейчас

Методист и лектор

Разрабатываю курсы по JavaScript и React в онлайн‑университете Нетология. Веду лекции по асинхронному программированию, продвинутым возможностям JS и интеграции React с другими библиотеками.

QEEP‑Pro
11.2016‑06.2018

Фулстек разработчик

QEEP‑Pro специализируется на создании CRM и ERP систем. Я писал внутренние продукты и работал над заказными проектами для Procraft, Фонда развития малого и среднего предпринимательства и локальных служб доставки. Привил практику непрерывной интеграции приложений, настроил CI. Руководил командой из 3 разработчиков.

Freelance
01.2014‑11.2016

Веб‑разработчик

Верстал сайты, писал jQuery‑плагины, поднимал и дорабатывал CMS. Сделал свою CMS на PHP, запустил на ней 5 сайтов.

Статьи

Легкий фронтенд

Современный веб пронизан фреймворками. Это не плохо! Проекты запускается быстро, а поддерживать их легко. Но иногда стоит избегать использования сторонних решений.

Сайты должны быстро грузиться при любом интернете и хорошо работать на любом этапе устройстве. Если сайт маленький, то добиться этого легко отказавшись от фреймворков и используя только HTML/CSS/JS.

Довольно легко построить статический сайт быстро, не потерять в поддерживаемости и качестве кода.

Как

Обычно, когда берут генератор статики на React (Vue, etc), хотят получить удобный компонентный подход. Есть способ добиться аналогичного результата без такого большого оверхеда. Для повторного использования разметки лучше взять любой шаблонизатор (twig, pug) и делать в нем миксины. CSS же отлично изолируется БЭМ‑нотацией или CSS-модулями (да, и их можно использовать просто так).

Отказ от фреймворка не означает возвращение в прошлое. Можно все еще использовать современные возможности JS и CSS, и обрабатывать их Babel и PostCSS (а для разметки возьмите PostHTML).

Хитрый шаблонизатор, пост‑процессоры и транспайлеры нужно как-то удобно запускать, чтобы на выходе получать набор файлов понятных любому браузеру. Тут можно взять абсолютно любой бандлер, но лучше посмотреть на максимально простые в конфигурации — Parcel, Rollup.

Еще

  • Обратите внимание, сколько будет весить JS который вы написали. И сравните с весом любимого фреймворка. Для контроля размеры бандла используйте size‑limit.
  • Все это будет бесполезно, если не следить за интерфейсными изображениями на сайте. Посмотрите доклад Вадима Макеева.
  • Подумайте о полифилах. При таком стиле разработки сайта никто за вас не включит в бандл полифилы, потому следует четко понимать какие возможности в каких браузерах есть и следить за этим.

Построение таких сайтов изменяет мышление и будет полезно любому фронтенд разработчику. Попробуйте!

Как работать с денежными значениями в JavaScript

Деньги везде. Банковские приложения, интернет‑магазины, платформы для фондовых бирж, мы встречаемся с деньгами каждый день. И все чаще мы доверяем работу с деньгами технологиям. Перевод статьи о частых ошибках и принятых шаблонах при работе с денежными значениями.

Процесс подготовки npm‑пакета

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

Чистая архитектура. Конспект книги Дядюшки Боба

Почему архитектура важна

  • Если строить приложение на скорую руку цена новых фич очень быстро растет. В какой‑то момент развитие продукта может и совсем остановиться.
  • «Потом сделаем нормально» — «потом» никогда не наступит и приложение превратиться в тыкву.
  • То что можно сделать быстро и плохо, выйти на рынок, а потом исправить все — миф. После выхода на рынок будут давить конкуренты и другие причине не делать хорошо.
  • Желание все переписать с нуля — оно от лени. Любое приложение можно привести в порядок итеративно. Некоторые сложнее, некоторые проще, но любые можно.

Ценность программы

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

На самом деле, структура — бóльшая ценность. Если программа работает правильно, но в неё нельзя вносить правки, она быстро придет в негодность. Если программа работает неправильно, но можно вносить правки без проблем, то ее легко заставить работать правильно. Выбор между этими двумя ценностями — всегда борьба. И разработчики должны убеждать другие заинтересованные стороны, что структура важнее поведения.

Тесты

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

Парадигмы

Программы формулируются на основе трех парадигм. Первым широкой публике стало известно структурное программирование. Предлагается отказаться от переходов (go to) в пользу условных операторов (if‑then-else) и циклов (do-while-until). Таким образом, структурное программирование накладывает ограничение на прямую передачу управления.

Потом пришло ООП. Сразу разрушение нескольких ошибочных суждений:

  • Это не про связывание данных и функций над ними — cat.walk() эквивалентно walk(cat).
  • Это не про инкапсуляцию — ее можно организовать через заголовочные файлы в C, или через замыкания.
  • Это не про наследование. Можно было и раньше, просто довольно криво. Да и вообще это часто вредное свойство ООП‑систем.
  • Это не про полиморфизм. Обеспечить полиморфное поведение можно имея в распоряжении только функции.

На самом деле, ООП дало важный концепт — инверсию зависимостей. А это позволило писать системы основанные на плагинах, которые легко расширять и изменять. Не так давно писал об этом. Короче, объектно‑ориентированное проектирование накладывает ограничение на косвенную передачу управления.

В моду вошло ФП. Главный принцип функционального программирования — иммутабельность данных. То есть запрет за изменение значений. Это даёт кучу бенефитов. Например, программы можно безболезненно выполнять на разных компьютерах, а потом результаты соединять в один. Легче держать в голове программу, когда в ней ничего никогда не изменяется Короче, функциональное программирование накладывает ограничение на присваивание.

Эти три парадигмы программирования не добавляют нам новых возможностей. А напротив, ограничивают нас в чем‑то. Вынуждают разработчиков делать больше работы. Это позволяет строить более надёжные программы, которые легко адаптировать к новым требованиям.

SOLID

S — Принцип единственной ответственности многие понимают не так как надо. Он не про то, что каждый модуль должен делать что‑то одно (хоть это и правильная мысль, она просто не имеет отношения к этому принципу). На самом деле, он постулирует что только у одной группы заинтересованных лиц должна быть причина изменять модуль.

Пример: есть класс пользователя. На нем определены методы: сохранить, рассчитать зарплату, рассчитать отработанные часы. Проблемы: сохранение важном для администраторов базы данных, расчет зарплаты — для бухгалтерии, расчет отработанных часов — для отдела кадров. Тогда появляется опасность, что при выполнении требований одной из групп (их ещё называют акторами) разработчики что‑то сломают для другой группы. Потому таких ситуаций следует избегать.

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

O — Программные сущности должна быть открыты для расширения и закрыты для изменения. Важно строить систему так, чтобы для добавления нового поведения не нужно было изменять старого кода. Идеальный вариант — написанный код не нужно модифицировать никогда, а только писать новый.

Пример: система выводит на веб‑странице какие то данные. В какой-то момент нужно выводить такие же данные в формате CSV. Если для этого нужно вносить изменения куда-то — это проблема. По хорошему, нужно просто написать ещё один модуль, который будет заниматься CSV.

L — Принцип подстановки Барбары Лисков — код должен иметь возможность работать с любым подтипом, так будто это базовый тип. Классическая ошибка — квадрат, как наследник прямоугольника. В таком случае клиентский код может попытаться изменить длины сторон прямоугольника независимо. Для квадрата это невозможно. Значит нельзя квадрат наследовать от прямоугольника. Простой принцип, который часто нарушают. Если соблюдать, можно избежать огромного числа ошибок.

I — Принцип разделения интерфейсов. Не стоит включать в программу зависимость от слишком большого модуля (если не используются все его функции).

D — Принцип инверсии зависимостей. «Наиболее гибкими получаются системы, в которых зависимости в исходном коде направлены на абстракции, а не на конкретные реализации.» Лучше не зависеть от деталей, потому что они нестабильны. Абстракции меняются реже. Но полностью соблюсти этот принцип не получится. Все равно кто‑то будет знать о конкретной реализации. Лучше чтобы это был кто-то один.

Архитектура

Архитектура — форма программного продукта. Цель этой формы — как можно дольше иметь как можно больше вариантов. Хорошая архитектура позволяет разрабатывать приложение максимально ровно (скорость разработки замедляется незначительно), легко доставлять его клиентам, поддерживать и сопровождать код. Одна из самых важных частей архитектуры — разделение бизнес‑правил и деталей. Бизнес важен, детали — нет. Нужно сохранять направление зависимостей. Детали зависят от высокоуровневых бизнес-политик, не наоборот.

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

Бизнес правила в приложении бывают двух видов. Критические бизнес‑правила. Они существуют и вне приложения. Если бы его не было, специалисты бы все равно применяли эти правила. Например, расчет процентов по кредиту. Программное обеспечение упрощает этот процесс, но не создаёт. Варианты использования. Они возникают благодаря приложению. Это некоторые правила, которые должно соблюсти ПО. Например, отображение вип-клиентов выше в списке. Первые важнее и стабильнее вторых. Потому варианты использования должны зависеть от критических бизнес-правил.

Фреймворк — детали. Приложение должно зависеть от фреймворка минимально. Нужно не писать «на фреймворке», а писать «с использованием фреймворка».

Признаки чистой архитектуры

  • Независимость от фреймворков
  • Простота тестирования
  • Независимость от пользовательского интерфейса
  • Независимость от базы данных
  • Независимость от любых внешних агентов