Русский
Русский
English
Статистика
Реклама

Techleadconf

Agreements as Code как отрефакторить инфраструктуру и не сломаться

09.10.2020 12:10:51 | Автор: admin


Это расшифровка выступления на TechLeadConf 2020-06-09. Прежде чем начнем, попробуйте ответить для себя на вопрос какие у вас ожидания от взаимодействия с инфраструктурой? Например сколько времени займет:


  • Развернуть новое окружение для тестов.
  • Обновить версию java и/или ОС внутри контейнера.
  • Выдать права доступа на сервер.

Спойлер результатов опроса во время TechLeadConf


А теперь умножьте свои ожидания на двое, и вы получите суровую реальность. Не приятненько как-то, да?



Особенно когда ты тот самый человек со стороны инфраструктуры, который говорит, что всё будет долго. Но так долго не потому, что я такой-сякой чопорный. Для этого, как правило, есть объективные причины. Давайте разбираться почему так происходит и что с этим делать.


Инфраструктура как она есть


Cлучайности + Договоренности + Процессы = Инфраструктура



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


  1. Случайность. Есть приложение. Но оно не появляется просто так, его разрабатывают вполне конкретные люди. Со временем или сразу появляется потребность развернуть/запустить приложение где-то(Спасибо Кэп!). В нашем случае лет 10-15 назад было отправлено письмо с просьбой смонтировать сервер в стойку. У кого-то это просьба в телеграмм чате настроить сервер. Суть в том, что инфраструктура это про то, что вас кто-то что-то попросил сделать, развернуть сервис. Изменения не происходят потому что вам так захотелось, за изменениями стоят люди.
  2. Договоренности. Со временем, случайные запросы на изменения через jira, email, slack могут перерасти в хаотичный поток запросов. В нашем случае необходимо было разворачивать множество окружений похожих на клиентские. Но бывает можно услышать "если хотите ускорить развёртывание, то не пишите нам в четверг, потому что мы ходим в серверную по средам". Появляются договоренности.
  3. Процессы. Апогеем становится преобразование договоренности в процесс. Появляется формальный процесс: заведите таску в jira, заполните необходимые поля и в течение 7 дней первый освободившийся инженер создаст вам новое окружение.

Инфраструктура стремится к хаосу



Как вы понимаете, монтаж серверов в стойку, процесс не быстрый, а разработка должна лететь. Но всё меняется, и приложение было контейнеризировано. Появилась возможность создавать динамически виртуалки на CoreOS и запустив compose файл получить окружение похожее боевое. Этакий k8s на минималках. И тут появился первый звоночек: а кто отвечает за YML файлике в git? Кто описывает инфру? Закономерно, код без присмотра начинает дурно пахнуть и привет групповая безответственность. Растет технический долг за счет быстрых и незаменимых подпорок из велосипедов. Меняется команда с одной стороны, потом с другой. И всё. Приплыли. Наступает ОПА момент когда инфраструктура работает, но никто не видит картинку целиком и не понимает почему она работает именно так. Это ни хорошо и ни плохо. Это данность: Инфраструктура стремится к хаосу, как и наша вселенная стремится к тепловой смерти.


Как бороться с Хаосом?


Бумажки и инструкции на защите от хаоса



Написать инструкции может прийти первым на ум, когда вы захотите бороться с хаосом. У меня тут есть, забавная история, как в одной ооооочень большой организации любили писать бумажки почти на каждый чих. Однажды, там для переезда сервиса согласовали временную схему сети на пару недель и выставили сервис в интернет. Соль в, том что я нашел это спустя пять лет. А на минутку это: нефтебаза в аэропорту с доступом в сеть ЦОД. Не хорошо как-то. Бумажка есть, а реальность показывает другое.


Agreements as Code



Аналогичная ситуация будет с задачами в Jira. Вас попросили, подготовить новое окружение. Вы что-то сделали и забыли как-оно там было настроено. Но если те же договорённости формализовать в виде кода. Пусть даже на своем DSL, или просто кодом на Ansible написали. Итогом у вас есть воспроизводимое решение и единая точка правды. Кто-то то поправил код в репозитории и вот обновленная версия приложения уже в проде. Но стоит ли это все эти договоренности автоматизировать? Стоит ли овчинка выделки?


Agreements as Code внедрять нельзя забить



Для ответа на вопрос автоматизировать или нет процесс/договоренности я выработал матрицу для принятия решений. Она концептуально похожа на матрицу Эйзенхауэра.


  • *ОПА степень "проблемности" проблемы. Насколько вы/ваши коллеги/заказчики страдаете.
  • Стоимость решения сколько времени/денег стоит решить проблему.


Рассмотрим краевые случаи:


  • Проблема огромная, решается дешево надо делать. Инструкция по заведению пользователей из confluence который пользоваться каждый день, замечательно заменяется скриптом, который формализует договоренности.
  • Проблема маленькая, решается дешево спорно, делать по остаточному принципу. Разбираться с REST api редкого сервиса, чтобы раз в год обновить DNS может быть не лучшим выбором для инвестиции времени. Но на долгой дистанции может пригодиться.
  • Проблема маленькая, решается дорого игнорировать. Как часто вам приходится обновлять подпись к email? раз в год? в три?
  • Проблема огромная, решается дорого спорно, необходимо десять раз подумать, т.к. без опыта можно сделать только хуже. Например, скриптики которые автоматизировали процессы и договорённости вдруг стали стандартом, все пользуют и не знают как оно работает. Собственно, та самая *ОПА когда вам надо рефакторить IaC.

Ручной труд -> Механизация -> Автоматизация



Предлагаю взглянуть на проблемы под другим взглядом и чуть шире. Процессы могут быть автоматизированы до различной степени.


  • Ручной труд нет автоматизации, вы руками проделываете всё, собираете шишки и понимаете, как выглядит процесс и какие в нем бутылочные горлышки.
  • Механизация первые попытки упростить себе жизнь. Статья в confluence с собранными шишками превращается в скрипт автоматизирующий отдельные проявления рутины. Но требующий человека для принятия решений.
  • Автоматизация "Слава роботам"(с) Бендер. Человек задействован минимально, появляются различные * as Service и позволяют другим людям автоматизировать их работу.


Когда эволюционировать и переходить на следующий уровень автоматизации, а когда нет?


  • Проблема огромная, автоматизируется легко надо делать. Заведение пользователей замечательно заменяется интеграцией, например, с LDAP и решает проблемы на корню. Инструкция -> скрипт -> LDAP.
  • Проблема маленькая, автоматизируется легко имеет смыл, т.к. на дальней дистанции можно переиспользовать наработки и не изобретать велосипед по новой, ваше знание сохранено и со временем может перерасти в сервис. Если посмотреть на AWS, то предоставляется множество * as Service на любой вкус, а ведь когда-то оно тоже могло начинаться с простого скрипта. Например, я завел приватный репозиторий, где хранятся такого рода скрипты.
  • Проблема маленькая, автоматизируется сложно скорее нет. Но для кого-то даже такое редкое действие как обновление подписи к email может быть актуально, у нас на дружественном проекте такое разрабатывают; говорят, что у одного крупного аутсорсера есть специальный web портал на котором можно получить свою подпись.
  • Проблема огромная, автоматизируется сложно скорее да, если ваши договоренности представлены в виде кода, то когда настанет *ОПА(а это неизбежно, т.к. всё стремится к хаосу!), у вас будет возможность отрефакторить код.

По мере развития инфраструктуры, договоренности формализуются в виде кода и стремятся стать * as Service.


Инфраструктуру можно и нужно рефакторить. Но не всегда


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


  • Разобраться как оно работает и удовлетворить собственное эго.
  • Ускорить внесение изменений.
  • Уменьшить количество падений сервисов
  • ...

Ansible: Миграция конфигурации 120 VM c Coreos на Centos за 18 месяцев



В моем случае, досталось в наследство самописное configuration management решение. Оно представляло инфраструктуру в виде кода, оно работало, но его поддержка было сложной, т.к. оно было хрупкой, никто не хотел его поддерживать. Планомерным итогом стала замена его на Ansible, подробности можно глянуть тут Ansible: Миграция конфигурации 120 VM c Coreos на Centos за 18 месяцев. Почему 1,5 года заняла миграция? Ответ прост 80% был reverse engineering как оно работает и только 20% непосредственно написание плэйбуков, ролей и миграция. Сам же процесс был прост:


CFM 2 Ansible


  1. Сформировать список серверов.
  2. Выбрать сервер из списка не перенесенных.
  3. Зафиксировать текущие договоренности.
  4. Разобраться как работает.
  5. Описать в виде кода.
  6. Вернуться на пункт 2.

Как начать тестировать Ansible, отрефакторить проект за год и не слететь с катушек


Ansible refactoring


На дружественном проекте занялись автоматизацией развертывания окружений у заказчиков и делали это через Ansible. Но спустя какое-то врем пришло понимание, что получившиеся плэйбуки страшно запускать на боевых серверах, т.к. нет уверенности что они не свалятся с ошибкой. Ситуацию еще усугубляло то, что до клиентов был air gap(инженеру могло потребоваться прийти на площадку к заказчику где нет интернета). Задача была стабилизировать плэйбуки и наладить процесс выпуска. Как решали можно почитать в Как начать тестировать Ansible, отрефакторить проект за год и не слететь с катушек, но если кратко:


  1. Составить список существующих ролей.
  2. Выбрать одну роль.
  3. Покрыть тестами и зафиксировать текущие договоренности.
  4. Внести правки в плэйбуки/роли, исправив причины падения.

Как реализовано тестирование Ansible ролей?


Ansible testing


Так исторически сложилось, что использовался репозиторий в котором лежали все роли. Был создан Jenkins Pipeline, который:


  1. Вычитвает конфиг из репозитория что тестировать.
  2. Генерирует динамически стадии для Jenkins.
  3. Запускает lint для всех ролей и плэйбуков.
  4. Запускает molecule для всех ролей

Реафаторинг IaC


IaC refactoring


Мы то с вами помним, что инфраструктура эволюционирует и формализуется в скрипты и/или множество * as Service. А с этим можно работать как с кодом и переиспользовать практики по рефакторингу кода. Из предыдущих сценариев выбивается нечто общее:


  1. Определяем измеримую цель.
  2. Проверяем наличие нужных знаний и времени на изменения.
  3. Выбираем маленький кусочек инфраструктуры.
  4. Разбираем что он делает.
  5. Формализуем договоренности и покрываем их тестами.
  6. Отдыхаем(это важно! иначе сгоришь оставив недоделанным работу).
  7. Повторяем.

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


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

Ускоряем ускорение



Со временем, внесение изменений в договоренности, в IaC может замедлиться и это нормально. Долго думал, как формализовать договоренности, и пришла идея изобразить историю развития проекта в цифрах и поискать закономерности. На график изображено:


  • Синяя линия Количество строк в YML файлах. Сложно померить договоренности, но можно допустить, что кол-во виртуальных машин коррелирует с ними.
  • Красная заливка Количество тестируемых Ansible ролей и плэйбоуков.
  • Маджентовая линия Количество инженеров поддерживающих и улучшающих инфраструктуру.

По графику можно увидеть, что:


  • Количество кода растет линейно и прогнозируемо.
  • Количество тестов отложенное коррелирует с количеством кода и растет по экспоненте.
  • Количество инженеров константно.

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


Используй IaC testing pyramid. Не откладывай не потом!


IaC testing pyramid


Годом ранее на DevopConf рассказывал Что я узнал, протестировав 200 000 строк инфраструктурного кода и подробно рассмотрел пирамиду тестирования инфраструктуры. Ровно таже идея, что в разработке, но для инфраструктуры: идем от дешевых быстрых тестов, которые проверяют простые вещи, например отступы, к дорогим полноценным тестами разворачивающих цельную инфраструктуру.


  • Static Analysis Статистический анализ кода, без запуска. Линтеры, например.
  • Unit IaC должна состоять из простых кирпичиков и вот их тестируем. В случае Ansible это роли тестируемые при помощи Molecule.
  • Integration Очень похожи на unit, но представляют комбинацию ролей описывающих целевую конфигурацию сервера.
  • E2E Цельная инфраструктура, состоящая из множества серверов.

Когда начинать писать тесты?


Ок, договоренности в инфраструктуре можно представить как код. А потом можно рефакторить. А если есть тесты то еще и не закопаться в рефакторинге. Но вот вопрос, когда начинать писать тесты? Рассмотрю пару проектов.


Проект 1



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


Проект 2



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


Вынесенный урок, что перевернутая пирамида тестирования не работает и с тестами не надо затягивать. Можно ориентироваться на такие цифры SLOC:


  • 2000 линтинг должен быть.
  • 4000 пора делать юнит тесты
  • 6000 время интеграционных тестов.
  • 8000 E2E тесты мерещат на горизонте.

Lessons learned


  1. Инфраструктура стремится с хаосу.
  2. Agreements as Сode внедрять нельзя забить.
  3. Ручной труд -> Механизация -> Автоматизация.
  4. Инфраструктуру можно и нужно рефакторить. Но не всегда.
  5. Тесты на инфраструктуру удешевляют/ускоряют ее изменения.
  6. Используй IaC testing pyramid. Не откладывай не потом!


Подробнее..

Как продать технические задачи бизнесу

23.04.2021 12:19:27 | Автор: admin

Поддерживать высокое техническое качество кода прямая обязанность техлида. Но чтобы этого добиться, зачастую приходится доказывать начальству и заказчикам необходимость вкладывать в улучшение кода силы и время. Как сделать это, не стаптывая в бесконечных согласованиях железные башмаки и не стирая язык до мозолей? Об этом в своем докладе на конференции TechLead Conf 2020 Online рассказал консультант Better Life Company Алексей Дерюшкин.

Приведенные в статье примеры и истории помогут читателям выстроить баланс между продуктовыми и техническими задачами в диалоге с заказчиком и руководителями. А проверенные на практике советы правильно подготовиться к этому разговору.

При подготовке к докладу Алексей надел шапочку техлида и решил ответить на два вопроса. Чего ему самому не хватало в то время, когда он был техлидом? И что может сделать техлид для того, чтобы команда стала более успешной и начала добиваться лучших результатов?

Проблемы Алексея выглядели так:

  • Бизнесу совершенно неинтересно, что находится под капотом и как сделать код лучше;

  • Бизнес не разбирается в системе и не хочет это делать;

  • Сам техлид не умеет вести переговоры;

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

Почему?! Потому что техлид говорил о каких-то технических вещах, а коллегам из бизнес-подразделений не интересно, как это работает. У них другие цели и задачи: как повысить конверсию, как привлечь больше людей, как сделать классный продукт. И технические детали им не интересны.

Из-за этого непонимания техлид не может продать идею. К тому же не все умеют уговаривать людей и просто продавать что бы то ни было. Недопонимание накапливается, и в итоге : Блин, да что с ними спорить? Я ему рассказываю, как надо сделать, а он ничего не понимает. Не буду этим заниматься в следующий раз!

У вас были ситуации, когда не получилось договориться с бизнесом? Если ответ да, контент ниже будет вам полезен.

Чем продажа идеи отличается от программирования?

Спойлер: ничем!

Есть три ключевые вещи, которые обязательно нужно сделать для того, чтобы успешно продать какую-то идею:

  1. Подготовиться заранее. Если вы не обучались продавать свои идеи, то выйти и свободно вести разговор в нужном русле может быть сложно.

  2. Взять готовый алгоритм. Люди уже очень давно (гораздо дольше, чем программируют), продают друг другу и материальные вещи, и идеи, и концепции. Зачем выдумывать велосипед, когда можно взять то, что уже работает?

  3. Использовать эмоции. С ними тоже нужно уметь работать. Но чтобы сделать это правильно, лучше пойти на какой-нибудь тренинг по эмоциональному интеллекту.

Пример неудачной продажи

Техлид приходит к владельцу продукта:

  • Привет! Я хочу добавить в этот спринт задачу по рефакторингу.

  • Привет! Нет, в этот спринт мы должны выпустить новую фичу, мы уже обещали.

  • У нас уже большой техдолг, мы все время торопимся и выпускаем фичи на костылях...

  • Ну, делайте сразу нормально, кто ж мешает?

Это результат неподготовленного диалога.

Давайте разберем ошибки типичного диалога техлида с бизнесом:

  • Птичий язык: владельцу продукта непонятно, о чем мы говорим;

  • Готовые решения. Человек, которому мы продаем идею, не участвовал в ее разработке. Он не знает, почему эта идея ему нужна и как она связана с тем, чего он хочет добиться;

  • Потребность убедить в своей правоте, а не помочь решить проблему бизнеса.

Итог закономерен: бизнес чувствует себя дураком, искренне не понимая, зачем нужно делать техдолг, когда можно сделать фичу.

Система продаж Джордана Белфорта

Есть замечательная цитата:

В фильме Волк с Уолл-стрит с Леонардо ДиКаприо прототипом главного персонажа является Джордан Белфорт один из самых известных продавцов и автор системы продаж.

На чем основывается его система? Джордан утверждает, что у вас купят идею (а на самом деле купят что угодно: телефон, автомобиль и т.д.), если есть 100% уверенность:

  • В идее (продукте, предложении);

  • В вас, как эксперте;

  • В людях, которых вы представляете.

Рассмотрим бытовой пример: вам продают автомобиль.

  • Идея 71%

Вы не совсем уверены, что автомобиль нужен вам как продукт. Но все же вам нужно ездить из пункта А в пункт В (на дачу, возить ребенка в школу).

  • Эксперт 83%

Вы почти уверены в продавце. То есть человек, который показывает вам автомобиль в салоне, вызывает у вас доверие.

  • Команда 78%

Вы также достаточно уверены в том, кого представляет продавец. Это может быть известная компания по продаже автомобилей или определенная марка. Например, вы уверены в том, что ес ли купите Mercedes, он не развалится в первый день, и не уверены в том же самом с АвтоВАЗом.

Если во всех трех пунктах ваша уверенность 100% или близко, то скорее всего, автомобиль вы купите.

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

Вернемся к примеру с автомобилем, и рассмотрим вариант, когда вы не купили машину:

  • Идея 0%

  • Эксперт 100%

  • Команда 100%

Автомобиль вам не нужен, в принципе. В автосалон вы зашли, чтобы согреться или спрятаться от дождя.

Если вы уверены, что автомобиль вам нужен, но при этом вы не доверяете продавцу вам кажется, что он хочет вас надуть или впарить 100500 опций, то конкретно у этого человека вы не купите:

  • Идея 100%

  • Эксперт 0%

  • Команда 100%

В случае, когда вы не хотите связываться с АвтоВАЗом, и LADA Granta не ваша мечта, будет так:

  • Идея 100%

  • Эксперт 100%

  • Команда 0%

То есть если даже один параметр будет не 100%, а 30-40% и ниже, вы не убедите человека купить автомобиль. А на месте техлида не продадите идею сделать тесты, что-то автоматизировать или провести рефакторинг.

Важный момент по поводу 100 баллов из 100. Вы можете только предполагать, каковы цифры на самом деле. Странно было бы на переговорах говорить человеку: А ну, скажи мне: от 0 до 100, насколько ты во мне уверен?. Это просто метафора, а не цифры, которые можно использовать в разговоре.

Как добиться уверенности на 100\100\100?

Идти по алгоритму.

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

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

Алгоритм продажи чего угодно, в том числе идей

Первые четыре секунды

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

Будьте доброжелательны и энергичны, но не слишком: не как персонаж из Маппет-шоу. Чуть-чуть энергичней, чем собеседник уже очень хороший уровень.

Кратко изложите, зачем пришли (позвонили, назначили встречу). Человек, скорее всего, чем-то занят, это элементарная вежливость.

Спросите, есть ли время на обсуждение? Это важно, особенно, если разговор спонтанный. Например, вы увидели в коридоре человека, с которым давно хотели поговорить. Он должен дать прямое согласие на то, чтобы пообщаться с вами.

Раппорт

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

Отсутствие раппорта очень хорошо описывает картинка:

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

Сбор информации

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

Давайте посмотрим на три пункта:

  • Боли ярко окрашенные негативные эмоции;

  • Выгоды позитив;

  • Цели и задачи более нейтральные вещи.

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

Основная презентация и предложение о покупке

Когда мы рассказываем о своей идее, обязательно нужно говорить на языке того человека, с кем мы общаемся. То есть на языке бизнес-целей!

Строим презентацию по схеме:

  • Как ваша идея поможет собеседнику?

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

  • Визуализируем ужасное будущее;

  • Визуализируем хорошее будущее;

  • Если это нужно, даем МИНИМУМ технических деталей;

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

  • Называем цену.

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

Очень хорошая фраза, которая отдает мячик вашему собеседнику после презентации:

Мне кажется, это хорошая идея. Что скажешь?

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

Перенаправление на рост уверенности.

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

  • Спросите, что смущает, и развейте страх

Если у вас не купили, значит, нет уверенности. Надо выяснить, где провал, почему 50% вместо 100%. И постараться это починить. Возможно, собеседник скажет напрямую:

  • Я не уверен, что это поможет.

Об идее, скорее всего, можно говорить прямо. Но вряд ли человек скажет:

  • Я тебе не доверяю, как специалисту.

Или:

  • Мне кажется, твоя команда не справится.

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

Снижение порога действия

Бывает, что человек во всех трех шкалах уверен на 100%, но при этом ничего не делает. Почему так происходит? Есть такое понятие порог действия нужно, чтобы сама покупка была легкой. И под конец взаимодействия мы должны сфокусироваться на нем, чтобы человеку было легко войти в сделку, принять идею и начать что-то делать.

Итак, на предыдущем этапе во всех трех пунктах набралось по 100 баллов, мы молодцы, идея классная, она нравится нашему собеседнику. Однако ему нужно совершить очень много действий, чтобы реализовать озвученную идею. Например, вы предложили ему что-то автоматизировать, но для этого он, дорогой ваш владелец бизнеса, должен подать заявку, чтобы она прошла через бюрократическую систему. Ему проще сказать: Да ну его на фиг! и убежать, чем соглашаться на такую длинную историю.

Поэтому вы должны постараться обеспечить легкий вход, например:

  • Просто кивни, мы все сделаем сами.

  • Тебе ничего не надо будет делать.

  • Мы уже попробовали, и вот результат...

Последний вариант идеальный. Вы делаете большую часть работы за него. Или, как минимум, делаете так, чтобы собеседнику не пришлось слишком много об этом думать.

Усиление боли

Это визуализация страшного будущего, в котором ваш собеседник не согласился на вашу идею:

  • Если ничего не поменяется, то...

  • Знаешь ли ты, что будем, если мы этого не сделаем?

  • Через год станет

Если мы сейчас не автоматизируем тестирование, то как мы будем тестировать через год, когда напишем еще больше кода? А что будет через год, если мы не купим новый сервер? Прямо спросите у человека про негативные сценарии будущего, пусть сам вам расскажет.

Закрытие сделки

Это опять передача мяча собеседнику:

  • Что дальше?

  • Ну что, попробуем?

  • Ты согласен, что...?

Это прямые вопросы, которые вы задаете собеседнику: Ну, как? Берем работу в следующий спринт? Ставим в план на следующий месяц?. Но эти вопросы часто просто забывают задать. Мы вроде бы обсудили идею и просто ждем, когда человек сам скажет: Ладно, давай. Я буду делать то-то и то-то.

Нет, пожалуйста, возьмите инициативу на себя и задайте вопрос: Ну как, работаем дальше?.

Пример

В 2015 году в одной из команд Алексей работал как техлид и на этапе подготовки он узнал о том, что сроки выхода в продакшн жестко зафиксированы, а в SLA на починку ошибки в продакшн выделено всего три дня.

То есть у владельца продукта есть две проблемы: жестко зафиксированы сроки и выхода в прод, и на починку багов. Если что-то из этого нарушается, владельцу продукта будет очень плохо. Поэтому продажа идеи была реализована через боль.

Диалог был примерно такой:

  • Привет! Я хочу обсудить одну техническую задачу, которая может ускорить время разработки задач и починки ошибок. Есть 10 минут, чтобы обсудить сейчас?

  • Давай.

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

Дальше идет презентация:

Смотри, сейчас у нас нет автотестов, и каждую фичу перед выпуском мы тестируем руками, ЭТО ДОЛГО. Я с ребятами УЖЕ ПОСЧИТАЛ, что если мы закроем 15% функционала тестами, то разработка каждой новой фичи УСКОРИТСЯ НА 2 ДНЯ. Благодаря этому мы сможем сделать на 10 фич больше до дедлайна. Мы все сделаем сами, надо просто взять в этот и следующий спринты задачи по разработке тестов. За этот месяц мы сделаем меньше фич, НО зато потом каждую будем делать быстрее. А еще это поможет быстрее чинить баги.

Что мы здесь видим? Во-первых, в презентации были указаны конкретные цифры. 15% функционала, 2 дня и 10 фич.

Во-вторых, был минимум технических деталей, а конкретно одна: 15% функционала надо закрыть. Цифра на самом деле не важна это может быть и 10%. Владельцу продукта важнее, что разработка новой фичи ускорится, или что баги будут чиниться быстрее.

В третьих, разговор был не про фреймворк тестирования и не про то, как будут проводиться тесты. Говорили про боль владельца продукта, а продавалась выгода от автотестов и новых фич.

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

В оригинале презентация была долгой, встреча на час. И одна из фраз, которая там прозвучала:

  • Представь, если мы будем и дальше также тестировать вручную, то с ростом функционала на тесты будет уходить все больше времени. Сейчас эту фичу мы делаем за 3 дня, а через полгода такую же будем делать 5 дней.

  • Что скажешь?

Это пример, как можно по такому алгоритму проводить продажи идей.

Полезные фишки

Есть полезные фишки, которые помогут в любом диалоге:

  • НО наоборот;

В предыдущем примере как раз используется эта фишка: мы сделаем меньше фич, НО зато потом каждую будем делать быстрее. Обычно мы говорим: Я сделал что-то хорошее, НО будет вот это и вот это плохо. То есть сначала обговариваем позитивные моменты, а потом идут НО и неприятные вещи. Поменяйте их местами: если есть что-то неприятное, сначала расскажите о нем, а потом о хорошем: Сейчас сделаем на 20% меньше фич, НО потом мы будем эти фичи печь как пирожки.

  • Потому что;

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

  • Визуализация;

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

  • Двойная петля;

Если вы видите, что собеседник сомневается (сначала у него есть один аргумент против, потом появляется другой, третий), скажите ему прямо: Мне кажется, что ты не уверен в идее, которую я принес. Расскажи, почему?. Так он попадает в двойную петлю: либо говорит: Нет-нет, я уверен, и начинает сам себе продавать уверенность, либо говорит: Да, я не уверен, и тогда дает вам аргументы, с которыми вы сможете работать.

  • Прямолинейность.

То, что вы честно и открыто ведете диалог, всегда подкупает.

Подводя итог

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

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

Кроме того, вы должны добиваться 100% уверенности по трем пунктам: в продукте, который продаете, в вас, как эксперте, и в людях, кого представляете.

Думайте о том, как помочь клиенту, а не как продать идею. И, наконец, следуйте приведенному в статье алгоритму. Его будет достаточно для того, чтобы ваши переговоры завтра или в следующий понедельник подросли в плане качества.

TechLead Conf 2021 пройдет 30 июня 2021и 1 июля 2021 в московской Radisson Slavyanskaya. Расписание можно посмотреть здесь.

Билеты на конференцию вы можете приобрести уже сейчас. Спешите: 1 мая цена станет выше!

Подробнее..

Книги, которые повлияли на меня как на разработчика и управленца

18.06.2021 12:04:53 | Автор: admin

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

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

За мою практику я прочитал немало книг, но некоторые оказали большее влияние на становление разработчиком, а затем управленцем. Я разбил книги по нескольким разделам.

Практика

Книги из практического блока можно просто читать, независимо от того, разработчик вы сейчас или руководитель. Они все классные. Я рекомендую их всем, и они довольно простые прочитали, и можно сразу использовать.

Specification by Example

Книга понравилась мне настолько, что побудила написать первую статью на Хабре. Гойко Аджич автор книги сам описывает ее как книгу о разработке ПО без единой строчки кода. Ее фокус находится на пересечении управления требованиями, проектного менеджмента, DevOps и тестирования (в том числе автоматизированного). Если DevOps часто описывают как infrastructure as code, то Specification by Example это своего рода requirements as code. Проработав некоторое время в корпоративном сегменте индустрии любой разработчик рано или поздно узнает о том, насколько неполными, неточными, противоречивыми и устаревшими бывают требования и насколько сложно, долго и дорого бывает переделывать программы, написанные по таким требованиям. Существуют тяжелые методы борьбы с этим недугом. Например ГОСТ 34 до сих пор используется в госсекторе, несмотря на то, что он безнадежно устарел.

Specification by Example гораздо более гибкая и менее формальная техника, позволяющая, впрочем, заказчику и исполнителю говорить на одном языке, понятном обоим. Кроме того, ГОСТы описывают форму проектной документации, но не дают конкретных советов по проектному управлению и никак не поощряют коммуникацию и совместную работу по улучшению требований и нахождению лучших (более быстрых, качественных и дешевых) способов решения проблем. Примеры переформулированных требований из книги гарантированно не оставят вас равнодушными. Техникой контрольных примеров мы пользуемся уже восемь лет, и она позволяет экономить какое-то невероятное количество времени и избегать недопониманий.

На основе техники, описанной в книге, даже разработан продукт SpecFlow. Нам он показался излишне громоздким. Но вам, возможно, подойдет. О связи требований и автоматизированного теста на примере SpecFlow можно почитать в этой статье.

Event Storming

Это даже не книга, а своего рода комикс. Если вы любите стикеры, доски и kanban, то event storming скорее всего тоже зайдет. Со временем мы пришли к тому, что большинство web-проектов сразу создаем на основе CQRS-архитектуры, даже если на старте хранилище данных всего одно. Это позволяет по мере развития проектов независимо оптимизировать стеки чтения и записи. И в момент, когда запросы к БД становятся уже совершенно безобразными, воткнуть очередь с денормализоваными хранилищами.

Подробно о всех преимуществах CQRS перед классической n-layer- и onion-архитектурой я рассказывал в докладе Быстрорастворимое проектирование.

Причем здесь Event Storming? Это техника специфицирования в терминах DDD, CQRS и Event Sourcing в форме увлекательной игры со стикерами, фломастерами и доской (доска может быть физической или виртуальной, но с физической гораздо веселее). С точки зрения наглядности, метод не успевает за Activity и BPMN-диаграммами. Но он гораздо более легковесный и прост в освоении и понимании.

Impact Mapping

И снова книга Гойко Аджича. Часть идей в ней пересекается со Specification by Example, но у книг разные целевые аудитории. Spec by Example лучше подойдет для разработчиков, архитекторов, тестировщиков, аналитиков и менеджеров среднего звена. Impact Mapping инструмент, в первую очередь, для бизнеса: владельцев продукта (или даже компании), маркетинга и топ-менеджмента. Spec by Example лишь поощряет общение с целью поиска оптимальных решений. Impact Mapping это формальный процесс для стратегического планирования. Его можно использовать не только в разработке ПО, но и для стратегического планирования, в целом. Например, в этом году мы использовали Impact Mapping для приоритизации и планирования задач в HR.

Теория + практика

Теоретически-практические книжки чуть более сложные. Я бы рекомендовал начать с DDD это очень холиварная тема! Возможно, DDD это не то, что вам нужно на этапе создания стартапа, но попробуйте обратить внимание не на технические аспекты, а на высокоуровневые паттерны. На то, как DDD предлагает общаться с экспертами, выделять главное, и на то, что продукт порой важнее используемых технологий. Если вам это зайдет, то дальше начнется протоптанная другими тропа: DDD -> CQRS -> Event Sourcing. Чаще всего все эти три темы обсуждаются в одном комьюнити. Как только вы разберетесь, что собой представляет каждая из концепций, вы поймете почему.

Немного особняком стоит книга Скотта Влашина про DDD в мире функционального программирования. Во-первых, ФП в изложении Влашина это не сложно. Обратите на книгу внимание хотя бы поэтому. Во-вторых, даже если в ближайшие десятилетия вы не собираетесь никуда сворачивать с тропинки объектно-ориентированного программирования, изучение других способов решения знакомых проблем может быть точкой роста. Я большой фанат гипотезы лингвистической относительности (и фильма Прибытие удачно выигрывающего эту гипотезу). В каком-то смысле знание языков программирования может влиять на ваше мировоззрение также, как знание естественных языков.

Теория

Факты и заблуждения профессионального программирования

Если эти книги вам знакомы или показались неинтересными, а вы хотите прочесть что-то более фундаментальное, рекомендую книгу Роберта Гласса Факты и заблуждения профессионального программирования. Она в свое время помогла мне перестать проваливать сроки реализации проектов, потому что я понял, что некоторые числа, которые были в моей голове, в три раза отличались от реальности. Книга хороша тем, что Роберт Гласс всю свою жизнь фактически проработал в аэрокосмической отрасли и собирал реальную статистику о том, сколько времени занимает анализ, разработка, тестирование, как неточны оценки, как часто меняются требования и как на самом деле сложно адаптироваться к таким изменениям.

Мифический человеко-месяц

Книга Фредерика Брукса, несмотря на то, что ей уже 100500 лет, и вы можете встретить в тексте что-то про перфокарты, это фундаментальный труд. Закон Брукса никуда не делся и, кажется, не денется. Понимание этого закона (девять матерей не родят дитя за один месяц) поможет принимать критические и зачастую контринтуитивные управленческие решения. Юбилейное издание включает в себя статью Серебряной пули нет, с которой тоже не грех ознакомиться всем и каждому.

Сколько стоит программный продукт

Большинство знает другую книгу МакКонела Совершенный код. Для кого-то она даже стала своеобразной Библией программирования. Если вы уже программируете хорошо и хотите научиться лучше оценивать трудозатраты на разработку, прочтите Software Estimation: Demystifying the Black Art (Сколько стоит программный продукт; в оригинале название звучит точнее, не находите?:). Книжка сложная, со статистикой, но ничего лучшего об оценке я не видел. Гарантирую, качество оценки тех, кто использует методы и советы из книги, многократно превосходит качество оценки тех, кто делает это по наитию.

Лютая теория и даже философия

Но если этого вам мало, и вы хотите улучшить свое умение думать о процессе, в целом, понять разницу между управлением, организацией и даже не прочь почитать что-то философское, то Г. П. Щедровицкий Оргуправленческое мышление это то, что вам нужно. Книга очень сложно читается, это конспект лекций для руководителей стройки атомных электростанций в СССР. На момент строительства никакой методологии Как строить атомные АС просто не существовало. Стройки велись по всему СССР, что делало каждый проект уникальным. В этих условиях успех строительства напрямую зависел от качества организации и от управления стройкой. В терминологии Щедровицкого эти два слова значат совсем не одно и тоже. В ходе лекций автор пытается найти баланс между первым и вторым. Труд просто фундаментальный и где-то философский, предназначенный для организаторов и руководителей с большой буквы.

Цель. Процесс непрерывного улучшения

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

На этом мой список книг подходит к концу. Выбирайте полезные для себя и enjoy!

TechLead Conf 2021 конференция, полностью посвященная инженерным процессам и практикам откроет свои двери уже совсем скоро: 30 июня и 1 июля она пройдет в Radisson Slavyanskaya (Москва).Расписаниеуже готово.Билетыв продаже. А ещё у нас открытдоступк докладам TechLead Conf 2020.

До встречи в офлайне!

Подробнее..

Моделирование микросервисов с помощью Event storming

28.01.2021 10:04:30 | Автор: admin

Event storming метод, который смещает акцент у событий с технического на организационный и бизнес уровни и помогает создать устойчивую модульную систему. Он нередко используется в контексте моделирования микросервисов. Но как применить его на практике?

При создании системы на микросервисах можно легко получить распределенный монолит. Event Storming не уберегает от этого на 100 %, но позволяет существенно снизить риск этого события. О том, как именно этого добиться, рассказал в своем докладе на конференции TechLead Conf 2020 практикующий консультант по архитектуре, процессам разработки и продуктовым практикам Сергей Баранов.

Как строить нашу микросервисную архитектуру быстрее, а команды делать более автономными при помощи Event storming?

Автор метода, итальянский программист Альберто Брандолини, дал свое определение.

Event storming это увлекательный способ собрать вместе разработчиков и экспертов в бизнесе для быстрого, совместного исследования сложной предметной области бизнеса. Часы вместо дней и недель.

Ключевое слово здесь исследование, потому что вначале Event Storming выглядит как своего рода хаос, со временем обретающий четкую структуру.

Альберто Брандолини достаточно смело заявил, что подобное исследование может занять часы вместо дней и недель. И практика показывает, что это действительно так. На момент написания статьи, Сергей провел сессии Event Storming уже более 150 раз: для больших предметных областей, для небольших стартапов и для крупных энтерпрайзов. И каждый раз это работало достаточно эффективно.

Структура

Структура Event Storming достаточно проста и многое взяла из DDD:

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

Допустим, речь идет о том, чтобы добавить товар в корзину. Команда приходит в агрегат (термин из DDD), либо уходит во внешнюю систему. Если команда может быть выполнена без нарушения инварианта агрегата, создается событие. Событие это факт и действие, произошедшие в прошлом. В отличие от команды, событие не может быть отменено (Товар добавлен в корзину).

На основе событий, например, обновляется модель чтения, цель которой помочь пользователю в принятии решений (Купи еще на 1000 рублей и получи скидку 10%) и выполнении последующих команд. Или же событие может активировать некое бизнес-правило. Которое, в свою очередь, вызовет команду, и цикл повторится.

Альберто Брандолини называет эту схему картинкой, которая объясняет все. По большому счету, так и есть: при повторении таких цепочек и получается наш конечный дизайн.

Процесс

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

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

Примеры событий:

  • Товар добавлен в корзину;

  • Товар оплачен;

  • Доставка оформлена.

Затем к этим событиям мы приписываем команды.

Все очень просто. Товар добавлен в корзину. Команда, которая относится к этому событию: Добавить товар в корзину.

Постепенно идет усложнение и появляются определенные бизнес-правила.

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

Появляются агрегаты. Агрегат это сущность или кластер сущностей, которые мы рассматриваем как единое целое. Допустим, у сущности Заказ есть свои сущности: Товары, Адрес доставки и пр. Наш интерес в том, что агрегат является транзакционной границей и отвечает за целостность и непротиворечивость всех данных, которые в него входят.

В нотации Event Storming агрегаты обозначаются желтыми стикерами. Вначале мы можем оставить эти стикеры пустыми, без названия. Мы пока не знаем, что это за агрегат. Просто будем собирать вокруг него те команды и события, которые, как нам кажется, должны обрабатываться вместе. А уже потом назовем его.

Агрегаты сбиваются вместе и образуют то, что в терминах DDD называется ограниченными контекстами. Они представляют из себя модель + общий словарь.

Ограниченные контексты должны быть максимально автономными. Такая автономность помогает в их рамках делать независимые друг от друга микросервисы. Хочу показать вам, как это выглядит на живом примере.

Стикеры на скрине мелкие. Но такая детализация выбрана не случайно: я хочу продемонстрировать объем происходящего.

Над этой схемой работали около пяти часов. Вначале выявили события, затем команды, добавили бизнес-правила. Со временем результатом командной работы стал сбор некоторых команд и событий в контексты. Например, контекст работы с ботами, контекст диалога с клиентом, контекст закрытия заявки.

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

В оффлайн это выглядит примерно так: перед нами огромная пустая стена, и около 40 человек генерируют:

  • События оранжевые стикеры;

  • Команды синие стикеры;

  • Агрегаты большие желтые стикеры. В данном случае агрегаты являются нашими потенциальными микросервисами.

Некоторые микросервисы включают в себя несколько агрегатов. Преимущество в том, что все они могут разрабатываться автономно. Можно было сделать это и в Big Design Up Front, долго собирая предметную область с помощью архитектора или гвардии аналитиков. Но, собравшись все вместе, участники получили этот результат примерно за 8-9 часов.

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

Контексты

Посмотрим на контексты чуть ближе:

В примере выше речь идет о страховании. Разберем 4 контекста:

  1. Поиск;

  2. Экспертиза;

  3. Авторизация;

  4. Загрузка справочников.

У них есть свои цели и своя ответственность. Например, цель экспертизы контроль повышения качества оказания услуг, а ответственность это поиск нарушений.

Проставим типы этих контекстов. В общем случае их три:

  1. Core основной контекст;

  2. Supporting поддерживающий контекст;

  3. Generic общий для всех.

Зачастую типы достаточно сложно определить. Люди в команде начинают о них спорить. Чтобы этого не произошло, можно использовать простую практику:

Выписываем контексты и спрашиваем, насколько Экспертиза обеспечивает наше конкурентное преимущество/насколько сложна ее реализация:

  • L сильное влияние/сложная реализация;

  • M среднее влияние/средняя сложность;

  • S слабое влияние/низкая сложность.

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

Дальше проставляем:

  • Core туда, где есть, как минимум, (L,L), (L,M);

  • Supporting туда, где нет особого конкурентного преимущества. В данном случае это загрузка справочников;

  • Generic (S, M).

Получаем такую картинку:

Казалось бы зачем нам все это нужно?

Решения по разработке

По очень простой причине: мы можем принять ряд решений.

Экспертиза останется во внутренней разработке. Здесь будут сосредоточены основные микросервисы с основной бизнес-логикой.

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

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

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

Стили коммуникации

Определяем, какими должны быть связи:

Это делается достаточно быстро. Здесь же мы обычно рассматриваем нефункциональные требования.

Например, для экспертизы они таковы: как часто экспертиза будет обращаться к авторизации, и какую пропускную способность должна авторизация держать.

У нас уже есть предметная область для экспертизы. И мы можем сказать, каким из этих элементов предметной области требуется постоянная авторизация доступа, или какие объемы данных будут передаваться из справочников. То есть появляются интеграционные связи. И на то, чтобы этого добиться, потребовалось меньше двух дней.

Протоколы взаимодействия

В качестве протоколов взаимодействия мы будем использовать Rest и RabbitMQ. Почему RabbitMQ? При загрузке справочников понадобится трансформация данных, не только чисто техническая, но и обеспечивающая защиту предметной области от протекания абстракций.

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

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

На протоколы взаимодействия по-прежнему ушло меньше двух дней.

Детали реализации

Ограниченные контексты мы строим так, чтобы они были автономными. Внутри каждого из них мы можем использовать легковесные подходы, вроде C4 от Саймона Брауна, для того, чтобы спроектировать каждый из этих контекстов в отдельности.

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

У нас есть общая картинка, сформулированные архитектурные ограничения. В рамках таких ограничений командымогут самостоятельно принимать инженерные решения.

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

  • Экспертизе подходит Postgres;

  • Авторизации Cassandra;

  • Загрузке справочников MongoDB;

  • Для поиска будем использовать CockroachDB.

У нас появляется свобода выбора и возможность принимать решения внутри своей команды. Почему так? Потому, что за рамками контекста находится четко определенный интерфейс.

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

Сервисы должны быть построены вокруг бизнес-потребностей и развертываться независимо. Event Storming позволяет очень быстро определить бизнес-потребности и достаточно быстро, через практики DDD, перейти к техническому решению.

К чему мы идем?

При помощи связки Event Storming + Domain-Driven Design получилось быстро и эффективно получить независимые контексты, в рамках которых могут жить наши микросервисы. Вполне вероятно, что в будущем появятся новые актуальные практики. Но на текущий момент именно благодаря Event Storming есть возможность сделать это быстро и автономно.

Выводы

  • Event Storming помогает быстро получить стратегический дизайн, определив границы, в рамках которых технические решения можно принимать автономно;

  • Если преднамеренно не нарушать границы на уровне реализации, то зависимости не появятся;

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

  • За счет автономности значительно упрощается управление техническим долгом;

  • Появляется возможность эволюционного развития к целевому видению.

Event Storming это не та сессия, которую можно провести, и забыть о ней. И бизнес, и архитектура развиваются. Поэтому приходится задействовать дополнительные сессии, дополнять события, проверять агрегаты.

Но повторные сессии занимают еще меньше времени. Ведь получается поддержать общее видение и общую ментальную модель. Наверное, это самое важное, что дает Event Storming.

Узнать еще больше подробностей о современных решениях для микросервисов, вы можете подписавшись на канал автора доклада, Сергея Баранова.

Хотите стать спикером TechLead Conf 2021? Если вам есть что сказать, вы хотите подискутировать или поделиться опытом подавайте заявку на доклад.

Следите за нашими новостями в Telegram,Twitter,VKиFBи присоединяйтесь к обсуждениям.

Подробнее..

Как писать читаемый код

19.01.2021 10:15:06 | Автор: admin

Бывает, что посмотрев на старый код, мы говорим: Его проще переписать, чем поменять. Печально, если речь идет о нашем собственном коде, с такой любовь написанном несколько лет назад. Head of Developer Relations в Evrone Григорий Петров в своем докладе на TechLead Conf 2020 разобрал проблемы, которые приводят к такой ситуации, и рассказал, как бороться с Software complexity problem.

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

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

Но несмотря на двадцатилетний опыт в программировании, Григорий признается: писать читаемый код до сих пор тяжело. И в этой статье мы обсудим все предполагаемые сложности.

Художник рисует мазками

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

Можно сказать, что программисты тоже пишут код своеобразными мазками: идентификатор за идентификатором, оператор за оператором, expression, statement, строчка за строчкой получаются творения в 10, в 100, в 1000 строк кода.

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

Поэтому одна из главных проблем, существующих в разработке софта это то, что мы называем Software complexity problem, что можно перевести на русский как проблема сложности программ.

Но ведь есть огромное количество других областей, где точно также накапливается сложность. Например, ракетостроение. У людей, которые делают космические корабли, немало сложностей, правда?

Но есть у них и годы обучения, которые начинаются прямо с детского сада. Будущие ракетостроители учат счет, вначале устный, потом письменный, потом приходят в школу, там изучают физику, математику. Проходят годы, они поступают в институт, где узнают, собственно, о строительстве ракет. У них есть устоявшиеся практики о том, как создавать ракеты, а навыки закрепляются повторением. Будущий ракетостроитель проектирует, экспериментирует, совершенствуется, и пятнадцатая по счету ракета таки выйдет за пределы атмосферы.

Проблемы программирования

  • Нулевая цена копирования;

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

  • Нет понимания как правильно;

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

  • Отсутствие фундаментального образования;

    Из-за молодости индустрии и нулевой цены копирования, в среде программистов отсутствует фундаментальное образование. Есть computer science, но это science. Она про науку, и имеет примерно такое же отношение к прикладной разработке софта как астрономия к разработке телескопов. Программист, который в университете 6 лет учил алгоритмы и структуры данных, почти ничего не знает про систему управления версиями, идентификаторы, про то, как писать читаемый код и рассказывать этим кодом истории.

  • Сложно посмотреть, как делают другие.

    Художник может прийти в картинную галерею, посмотреть на разные топовые картины и сказать: Вот это круто нарисовано. Я сейчас повторю и буду рисовать так же хорошо!. Для этого у него есть интуитивное мышление.

Интуитивное мышление, когнитивные искажения

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

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

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

Кроме того, программистам, в отличие от художников, трудно обучаться у мастеров. Мы, конечно, можем прийти в наш аналог картинной галереи GitHub и посмотреть там на большие проекты. Но если сделать чекаут проекта с GitHub, там может оказаться полмиллиона строк кода. Это очень много, а у нас нет оптического зума, чтобы просто окинуть код взглядом, не вникая. Поэтому обучаться на примере программистам очень тяжело. Про то, что GitHub это скорее склад строительного материала, а не картинная галерея, я даже говорить не буду.

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

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

Борьба со сложностью

К сожалению для нас, сложность из кода нельзя убрать. Ведь она это та польза, которую приносит написанная нами программа.

Но сложность можно перераспределить! Именно об этом пойдет речь в статье.

  • Память;

Гиппокамп это часть мозга, которая, предположительно, имеет отношение к формированию памяти. Известно, что когда выходит из строя гиппокамп, ломается память.

Как это происходит, не совсем ясно. Но существует такая закономерность, как Кошелек Миллера: когда человек смотрит на новые для себя объекты, в среднем, он может удержать в фокусе внимания от 5 до 9 из них.

Современные нейрофизиологи сделали вывод, что Миллер был большим оптимистом, и в реальности число удерживаемых в фокусе объектов ближе к 5. Именно столько новых штук может находиться в кратковременной памяти, прежде чем она начнет давать сбои.

Но у нас есть еще и долговременная память, объемы которой довольно велики. Однако помещение чего-либо в долговременную память занимает немало времени.

Когда человек только учится играть в шахматы, он медленно сканирует шахматную доску, вспоминая правила и пытаясь нащупать некие комбинации. Окно его внимания, содержащее 5 элементов, неспешно ползет по доске.

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

Когда опытный игрок в шахматы смотрит на доску, новой информации для него очень мало. Именно эта новая информация то, что он держит в кратковременной памяти, и речь обычно идет всего о 2-3 элементах. Все остальное уже есть в долговременной памяти. Но для такой подготовки требуются годы.

Библиотеки и фреймворки для языков программирования могут стать способом перевести информацию из кратковременной памяти в долговременную.

Если программист много лет пишет на Python и использует requests, он к ним привыкает. Типичные конструкции использования requests как сделать запрос, как передать и получить JSON, как решать вопросы скорости и задержек ему привычны. Код, который использует библиотеку, становится для программиста читаемым. В таком коде больше нет сложности. По крайней мере, для этого конкретного программиста.

Если же программист начинает использовать другую библиотеку, читаемость кода для него падает. Поэтому иногда выбор не оптимальной, с точки зрения скоростных или usability характеристик, библиотеки или фреймворка, которые, тем не менее, мега популярны, может быть разумным. Такой код будет намного читаемее для большого количества программистов.

Точно также работает стандарт кодирования, coding style. Код разработчиков может быть читаемым друг для друга, но только если они хотя бы несколько месяцев поживут с ним. Нейрофизиология утверждает, что несколько месяцев и несколько сотен повторений нужны нашей памяти, чтобы выстроить долговременные связи long-term potentiation, чем бы они ни были.

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

Но память это долго. Это самый простой, но и самый длительный по времени способ борьбы со сложностью.

  • Декомпозиция;

Второй по популярности способ это декомпозиция на части по 5 элементов.

Посмотрим на эволюцию типичной сферической программы в вакууме.

Как правило, она начинается с одного файла, который реализует минимум функциональности. Затем, по мере добавления строк кода, программист интуитивно начинает разделять программу на файлы поменьше. Еще через некоторое время, когда файлов становится несколько десятков, более-менее опытный программист выделяет модули, которые дает язык программирования.

Чуть позже программист начинает использовать абстракции языка. Обычно это классы, миксины, интерфейсы, протоколы, синтаксический сахар. Современные языки программирования, как правило, позволяют программисту бороться со сложностью путем добавления высокоуровневых абстракций и синтаксического сахара.

Через некоторое время, когда абстракции языка программирования исчерпывают себя, и строчек становится несколько десятков тысяч, разработчики начинают с интересом смотреть в сторону DSL: YAML, JSON, Ruby, XML и т.д.

Особенно большой интерес проявляется в Java, где XML-конфиги к программам просто стандарт де-факто. Но даже если команда не пишет на Java, она с большим удовольствием выкладывает и перераспределяет избыточную сложность в JSON, YAML и в другие места, которые сможет найти.

Наконец, когда строк кода становится очень много, программы начинают делить на модные сейчас микросервисы.

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

Хорошо, что у нас есть и другие инструменты для того, чтобы писать читаемый код.

  • Метаинформация.

Прежде всего метаинформация нужна не компилятору и языку программирования, а людям.

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

Главный, основной, фундаментальный дорожный указатель идентификаторы.

Идентификаторы это переменные, константы, названия функций и классов все те имена, которые мы даем сущностям в коде.

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

или Мосгорводоканалстрой это одна сущность для нашего мозга.

Идентификатор здорово помогает писать читаемый код, если отвечает на вопрос что это?. Программист пришел в проект, посмотрел на идентификатор, и ему сразу понятно, что. В современных языках программирования для этого есть PascalCase, camelCase, snake_case. Выбирая конкретный стиль, мы выбираем то, что привычнее нашей команде.

В Go все очень тяжело со сложностью, потому что язык практически не предоставляет синтаксического сахара. В книге Как писать на языке программирования Go есть параграф про эволюцию идентификаторов. Там написано о том, как бороться с когнитивной сложностью в коде. Выбирая имя для идентификатора, авторы предлагают смотреть на то, что находится рядом с этим идентификатором. Если там что-то очень простое (функция, 2-3 строчки кода, которые очевидны), то идентификатор может быть i или v:

v => users => admin_users

Но по мере увеличения сложности и количества кода, мы хотим увеличивать длину идентификатора, чтобы он лучше отвечал на вопрос что это?, если такая информация непонятна из контекста.

После идентификаторов идут комментарии, которые отвечают уже на вопрос зачем это?.

Худший комментарий в коде тот, который пересказывает, что происходит в коде. Но это и так можно увидеть, прочитав код! А вот информация зачем это происходит, как правило, содержится только в голове разработчика.

Топовые мировые программисты нередко пишут код вообще без комментариев. Идентификаторы, которые они используют для переменных, констант, функций, классов, и то, как они разбивают код на части с помощью предоставляемых языком программирования средств, рассказывают историю лучше самых удачных комментариев. Лучшим комментарием является сам код.

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

Например:

Точно также комментарии в коммитах могут давать понимание, зачем сделан этот коммит. А если в таком коммите есть ссылка на тикет, то сложность перераспределяется и туда, давая дополнительные точки опоры при чтении кода через много лет и отвечая на вопрос зачем это было сделано?.

Документацию же можно рассматривать в качестве последнего бастиона. Если не удалось сделать код, который отвечает на вопрос зачем?, не получилось добавить в него комментарии, которые отвечают на этот вопрос, и с комментариями в коммитах и тикетах тоже не сложилось, открываем readme.md и пишем там большой архитектурный абзац.

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

Автогенерация документации это отдельная история. Многие примеры хорошего кода, которые мы видим: фреймворки и библиотеки. При их изготовлении нам важна документация, поэтому мы документируем каждый метод, а потом автогенерим документацию. Но это нужно делать с умом.

В роли документации могут выступать и тесты. Поскольку они показывают пути выполнения.

В последние 5-10 лет в динамические языки программирования пришли типы. Они выполняют роль своеобразных капканов для ошибок. Когда программист пишет код, он может воспользоваться Gradual подходом современных языков. И там, где сложность повышена, добавить типы, чтобы в коде расставились несколько капканов.

Если программист через какое-то время (например, спустя полгода) воспользуется этим кодом неправильно, капкан сработает, подчеркнет ему строчку в IDE красным, и все сразу станет понятно.

Gradual подход к перераспределению сложности

Gradual подход к написанию читаемого кода по больше части вращается вокруг цифры 5.

Есть несколько способов перераспределения сложности:

  • Gradual decomposition;

    Если в нашем коде собралось больше пяти элементов, мы пробуем распределить их декомпозицией по файлам, по модулям, по классам, по функциям: в зависимости от того, что у нас есть в языке программирования.

  • Gradual meta information;

    Если мы понимаем, что у нас уже есть распределение на множество частей, начинаем добавлять метаинформацию: давать описательные имена идентификаторам, чтобы они отвечали на вопросы что это? и зачем это?.

  • Gradual typing.

    Наконец, когда сложность продолжает скапливаться, мы добавляем типы, как капканы на будущее. Чтобы по возвращению к этому коду через какое-то время, капканы сработали и защитили нас.

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

Вопрос о том, что такое новая вещь, остается немного за кадром. Это зависит от бэкграунда разработчика: сколько лет он пишет код, какие языки программирования, фреймворки, подходы знает.

Если в команде есть разработчики разного уровня (например джуниоры и сеньоры), они не смогут писать код, который будет читаем друг для друга. То, что не является новинкой для сеньора, который 20 лет пишет код, для джуниора ею будет. Поэтому код, который напишет сеньор, будет очень простой, понятный, хорошо читаемый но для сеньоров. А для джуниоров количество нового и, соответственно, сложности в таком коде будет зашкаливать.

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

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

Но в большинстве случаев Gradual подход, который крутится вокруг цифры 5, является неплохой стартовой точкой.

Конференция, полностью посвященная инженерным процессам и практикам, TechLead Conf 2021 пройдет 12и 13 апреля. Билеты можно приобрести здесь. Вы можете успеть купить их до повышения цены!

А пока мы все ждем апреля, приглашаем вас на Quality Assurance Webinar. На нем поговорим о пирамиде тестирования, узнаем, как найти UI тесты, которые легко могут быть перенесены на более низкие уровни, и разберемся в инфраструктуре тестирования в браузерах.

Мероприятие начнется 21 января в 18:00 мск. До встречи!

Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru