[1/2] Люди не понимают ООП
Меня заинтересовала статья авторства Флориана Бухбергера (Florian Buchberger) „People Don’t Understand OOP“ (русский перевод на Хабре), я кратко и вольно пересказываю её ниже. Мне представляется важным, чтобы системный аналитик разбирался в том, чем являются объекты и чем они не являются, когда анализирует предметную область и проводит онтологическое моделирование предметной области.
По-простому: рисует кубики типа «заказ», «счёт», «клиент» и соединяет их стрелочками с глаголами-описаниями взаимодействий.
Модель предметной области тесно связана с программированием: от грамотного моделирования зависит, как разработчики поймут инженерную документацию и как попытаются реализовать обеспечение бизнес-задачи в хранилищах данных и в коде.
TL;DR
Объектно-ориентированное программирование — это когда связанные состояние и поведение упаковываются в блоки (объекты). Из чего следует:
— Data Transfer Objects (DTO) — это не объекты, а записи;
— Сервисы, репозитории не хранят состояние и могут считаться функциями;
— Грамотно выделить объекты поможет опыт, есть пара советов.
Определение ООП
— Алан Кэй, американский учёный в области теории вычислительных систем, один из пионеров объектно-ориентированного программирования, в письме от 2003 года.
(1) «Объекты — это коллекции операций, разделяющих общее состояние» — Питер Вегнер
(2) «Объекты — это сущности, сочетающие в себе свойства процедур и данных, потому что они выполняют вычисления и хранят локальное состояние. Единообразное применение объектов контрастирует с использованием отдельных процедур и данных в традиционном программировании» — Марк Стефик и Дэниел Бобров
(3) «Объектно-ориентированные программы состоят из объектов. Объект включает в себя и данные, и процедуры, которые могут обрабатывать данные. Процедуры обычно называют методами или операциями» — Банда четырех
(4) «Объекты — единицы состояния, в общем случае непрозрачные снаружи. Однако объект может предоставить возможность взаимодействия со своим состоянием при помощи передачи сообщений (= „методов“)» — Тим Рентш
Классы для объектов не обязательны
Например, JavaScript и Lua используют концепцию прототипирования: использовать существующий объект как прототип для создания нового объекта.
Go и Rust используют структуры, которые похожи на классы.
Наследование
Чаще всего ассоциируется с ООП, хотя оно совсем не обязательно для ООП. Наследование позволяет объявлять новые классы на основе существующих и наследовать их атрибуты и методы. Более того, наследованием часто злоупотребляют там где лучше использовать агрегацию или композицию (примеры и разница), так что наследование вообще не рекомендуют использовать.
Полиморфизм
Позволяет изменять поведение в подтипах по сравнению с поведением базового типа. В отличие от наследования не затрагивается структура базового типа и не наследуется код; применение можно увидеть в интерфейсах (речь про абстрактные объявления сигнатур типов без реализации).
Подтипы
Собственно, реализация полиморфизма. Позволяет комбинировать разные типы, чтобы обрабатывать одинаковые сообщения — иными словами, иметь методы которые называются одинаково но делают разные вещи. Барбара Лисков предложила в 1987 году важный для ООП принцип:
#ооп
Меня заинтересовала статья авторства Флориана Бухбергера (Florian Buchberger) „People Don’t Understand OOP“ (русский перевод на Хабре), я кратко и вольно пересказываю её ниже. Мне представляется важным, чтобы системный аналитик разбирался в том, чем являются объекты и чем они не являются, когда анализирует предметную область и проводит онтологическое моделирование предметной области.
По-простому: рисует кубики типа «заказ», «счёт», «клиент» и соединяет их стрелочками с глаголами-описаниями взаимодействий.
Модель предметной области тесно связана с программированием: от грамотного моделирования зависит, как разработчики поймут инженерную документацию и как попытаются реализовать обеспечение бизнес-задачи в хранилищах данных и в коде.
TL;DR
Объектно-ориентированное программирование — это когда связанные состояние и поведение упаковываются в блоки (объекты). Из чего следует:
— Data Transfer Objects (DTO) — это не объекты, а записи;
— Сервисы, репозитории не хранят состояние и могут считаться функциями;
— Грамотно выделить объекты поможет опыт, есть пара советов.
Определение ООП
ООП означает для меня лишь обмен сообщениями, локальное сохранение, защиту и сокрытие состояния-процесса, и максимально позднее связывание всего вместе.
— Алан Кэй, американский учёный в области теории вычислительных систем, один из пионеров объектно-ориентированного программирования, в письме от 2003 года.
(1) «Объекты — это коллекции операций, разделяющих общее состояние» — Питер Вегнер
(2) «Объекты — это сущности, сочетающие в себе свойства процедур и данных, потому что они выполняют вычисления и хранят локальное состояние. Единообразное применение объектов контрастирует с использованием отдельных процедур и данных в традиционном программировании» — Марк Стефик и Дэниел Бобров
(3) «Объектно-ориентированные программы состоят из объектов. Объект включает в себя и данные, и процедуры, которые могут обрабатывать данные. Процедуры обычно называют методами или операциями» — Банда четырех
(4) «Объекты — единицы состояния, в общем случае непрозрачные снаружи. Однако объект может предоставить возможность взаимодействия со своим состоянием при помощи передачи сообщений (= „методов“)» — Тим Рентш
Классы для объектов не обязательны
Например, JavaScript и Lua используют концепцию прототипирования: использовать существующий объект как прототип для создания нового объекта.
Go и Rust используют структуры, которые похожи на классы.
Наследование
Чаще всего ассоциируется с ООП, хотя оно совсем не обязательно для ООП. Наследование позволяет объявлять новые классы на основе существующих и наследовать их атрибуты и методы. Более того, наследованием часто злоупотребляют там где лучше использовать агрегацию или композицию (примеры и разница), так что наследование вообще не рекомендуют использовать.
Полиморфизм
Позволяет изменять поведение в подтипах по сравнению с поведением базового типа. В отличие от наследования не затрагивается структура базового типа и не наследуется код; применение можно увидеть в интерфейсах (речь про абстрактные объявления сигнатур типов без реализации).
Подтипы
Собственно, реализация полиморфизма. Позволяет комбинировать разные типы, чтобы обрабатывать одинаковые сообщения — иными словами, иметь методы которые называются одинаково но делают разные вещи. Барбара Лисков предложила в 1987 году важный для ООП принцип:
Функции, которые используют базовый тип, должны иметь возможность использовать подтипы базового типа, не зная об этом. Простыми словами — классы-наследники не должны противоречить базовому классу. Например, они не могут предоставлять интерфейс ýже базового.
#ооп
🔥2
[2/2] Люди не понимают ООП
Инкапсуляция
Под инкапсуляцией обычно понимают сразу две вещи:
(1) Передача данных вместе с поведением; собственно то, что понимается под объектом.
(2) Сокрытие внутреннего состояния от внешних наблюдателей.
Рассмотрение инкапсуляции важно, потому что в архитектуре часто используется характеристика “(Object) coupling” and “(class) cohesion” — я даже не буду пытаться перевести на русский, потому что и coupling и cohesion в лоб переводятся одним словом. Речь о том, что в хорошей архитектуре объекты слабосвязаны, а классы узкоспециализированы.
Если говорят, что объекты сильно сцеплены (high coupling) то скорее всего они должны быть одним объектом на самом деле. Говорят, что class has high cohesion когда класс имеет ясное назначение и четкие границы ответственности.
Поэтому хорошая система „has low coupling and high cohesion“. Попробуйте запомнить :)
Инкапсуляция — сокрытие внутреннего устройства от внешних наблюдателей — позволяет менять внутреннюю структуру класса не боясь убить совместимость с использующим его кодом. Мы объявляем методы, с помощью которых можно менять состояние нашего объекта; мы можем переименовывать атрибуты, дополнять и менять их местами, не разрушая совместимость. Внешний наблюдатель даже не узнает, что мы что-то поменяли и код будет работать и дальше.
Так что же такое ООП?
ООП — это когда связанные состояние и поведение упаковываются в блоки (объекты). Дополнительными характеристиками ООП могут быть: классы, прототипы, инкапсуляция, подтипирование, наследование…
Мда, непросто.
Как понять, как именно выделять объекты? Когда несколько объектов — это на самом деле один объект, а когда он вообще не объект, а запись?
Короче, опыт и практика вам в помощь (погуглите, реально часто именно это и предлагается делать: пробовать и разбираться). Согласен, мерзко дочитать аж до сюда и обнаружить, что простого ответа нет; есть парочка средних:
(1) Можно начать с рекомендации от Банды четырех:
(2) Посмотреть запись вебинара Натальи Косиновой «Как разобраться в предметной области: инструкция по применению».
Объекты, которые на деле записи или функции
И напоследок,
Если что-то названо в коде объектом и содержит только атрибуты и, возможно, геттеры-сеттеры — это на самом деле не объект, а запись. Методы для присвоения или считывания атрибутов не сильно препятствуют усилению связанности объектов; и на деле не содержат никакой логики поведения.
Классы, которые в коде называются сервисами и репозитариями и не содержат внутреннего состояния — на деле с таким же успехом могут быть заменены обычными функциями в модулях. А синглтоны — это сложный способ объявить глобальную переменную…
Так что эти инфраструктурные штуки — записи и функции — в модели предметной области, скорее всего, будут отсутствовать, и теперь понятно, почему (потому что они не объекты ).
#ооп
Инкапсуляция
Под инкапсуляцией обычно понимают сразу две вещи:
(1) Передача данных вместе с поведением; собственно то, что понимается под объектом.
(2) Сокрытие внутреннего состояния от внешних наблюдателей.
Рассмотрение инкапсуляции важно, потому что в архитектуре часто используется характеристика “(Object) coupling” and “(class) cohesion” — я даже не буду пытаться перевести на русский, потому что и coupling и cohesion в лоб переводятся одним словом. Речь о том, что в хорошей архитектуре объекты слабосвязаны, а классы узкоспециализированы.
Если говорят, что объекты сильно сцеплены (high coupling) то скорее всего они должны быть одним объектом на самом деле. Говорят, что class has high cohesion когда класс имеет ясное назначение и четкие границы ответственности.
Поэтому хорошая система „has low coupling and high cohesion“. Попробуйте запомнить :)
Инкапсуляция — сокрытие внутреннего устройства от внешних наблюдателей — позволяет менять внутреннюю структуру класса не боясь убить совместимость с использующим его кодом. Мы объявляем методы, с помощью которых можно менять состояние нашего объекта; мы можем переименовывать атрибуты, дополнять и менять их местами, не разрушая совместимость. Внешний наблюдатель даже не узнает, что мы что-то поменяли и код будет работать и дальше.
Так что же такое ООП?
ООП — это когда связанные состояние и поведение упаковываются в блоки (объекты). Дополнительными характеристиками ООП могут быть: классы, прототипы, инкапсуляция, подтипирование, наследование…
Мда, непросто.
Как понять, как именно выделять объекты? Когда несколько объектов — это на самом деле один объект, а когда он вообще не объект, а запись?
Короче, опыт и практика вам в помощь (погуглите, реально часто именно это и предлагается делать: пробовать и разбираться). Согласен, мерзко дочитать аж до сюда и обнаружить, что простого ответа нет; есть парочка средних:
(1) Можно начать с рекомендации от Банды четырех:
«…Можно написать формулировку задачи, выделить существительные и глаголы, а затем создать соответствующие классы и операции. Или можно сосредоточиться на взаимодействиях и обязанностях в системе. Или можно смоделировать реальный мир и перенести обнаруженные объекты в архитектуру. Всегда будут разногласия о том, какой подход лучше»
(2) Посмотреть запись вебинара Натальи Косиновой «Как разобраться в предметной области: инструкция по применению».
Объекты, которые на деле записи или функции
И напоследок,
Если что-то названо в коде объектом и содержит только атрибуты и, возможно, геттеры-сеттеры — это на самом деле не объект, а запись. Методы для присвоения или считывания атрибутов не сильно препятствуют усилению связанности объектов; и на деле не содержат никакой логики поведения.
Классы, которые в коде называются сервисами и репозитариями и не содержат внутреннего состояния — на деле с таким же успехом могут быть заменены обычными функциями в модулях. А синглтоны — это сложный способ объявить глобальную переменную…
Так что эти инфраструктурные штуки — записи и функции — в модели предметной области, скорее всего, будут отсутствовать, и теперь понятно, почему (
#ооп
1👍6
[1/x] Как сделать правильное логгирование
Разрозненные логи довольно сложно анализировать, поэтому первое что надо сделать — это пробрасывать в логи сквозной идентификатор.
Проще объяснить по картинке:
При возврате ответа на синхронный вызов система A (и другие, которыми вы управляете) должна вернуть значение
Применение
Тестировщик проверяет вашу систему, вызывает постманом один из эндпоинтов. Получает в ответе
Как передавать и как возвращать
Можно в теле запроса и ответа, можно в HTTP-заголовках. Обычно я проектирую исходя из привычек команды и стиля, принятого на проекте. Если стиля никакого нет — то прививаю :)
А что там за span_id такой
Этот параметр похитрее, удобен если в контуре несколько (много) систем, которые вызывают друг друга разными хитроумными способами. Тогда первая система, обрабатывающая вызов, генерирует
Проще опять по картинке понять: получается что в логе вы увидите что-то вроде «0.4.2» и сможете понять, что запись сделала третья система в цепочке, но вызвана она была далеко не первой по порядку обработки.
Подробнее об этой технике можно почитать например в документации OpenTelemetry. Если заморочиться, то можно даже визуализировать такие вызовы в дерево и осчастливить техподдержку. Им и так нелегко разгребать всё это.
#логгирование
Разрозненные логи довольно сложно анализировать, поэтому первое что надо сделать — это пробрасывать в логи сквозной идентификатор.
Проще объяснить по картинке:
trace_id — это сквозной идентификатор, который либо передаётся на вход в вашу систему, которая первая принимает вызов от других систем вне контура либо от пользователя. Если на вход не передан trace_id, то система A его генерирует и дальше сохраняет в каждой записи своего лога и передает в вызовах в другие системы (B, C, D и E).trace_id удобно сделать GUID'ом, для экономии места убрать дефисы. На входе проверять, что trace_id — это валидный гуид, и норм. Если не валидный — генерировать свой.При возврате ответа на синхронный вызов система A (и другие, которыми вы управляете) должна вернуть значение
trace_id, который использовался в ходе обработки вызова.Применение
Тестировщик проверяет вашу систему, вызывает постманом один из эндпоинтов. Получает в ответе
trace_id, и по нему ищет в GrayLog или ELK все записи, относящиеся к этой операции. Особенно это удобно, когда задействовано несколько систем и логи сохраняются в общее хранилище; если у вас нет центрального хранилища логов, то самое время его завести.Как передавать и как возвращать
Можно в теле запроса и ответа, можно в HTTP-заголовках. Обычно я проектирую исходя из привычек команды и стиля, принятого на проекте. Если стиля никакого нет — то прививаю :)
trace_id можно передавать и в сообщениях через брокер, хотя тимлиды и архитекторы иногда сопротивляются, мол, лишнее, есть и технические заголовки. Я обычно выслушиваю киваю, и делаю по-своему (если хватает полномочий).А что там за span_id такой
Этот параметр похитрее, удобен если в контуре несколько (много) систем, которые вызывают друг друга разными хитроумными способами. Тогда первая система, обрабатывающая вызов, генерирует
span_id равный нулю «0». При вызове других систем эта первая система A добавляет к span_id порядковый номер вызова, начиная с «1».Проще опять по картинке понять: получается что в логе вы увидите что-то вроде «0.4.2» и сможете понять, что запись сделала третья система в цепочке, но вызвана она была далеко не первой по порядку обработки.
Подробнее об этой технике можно почитать например в документации OpenTelemetry. Если заморочиться, то можно даже визуализировать такие вызовы в дерево и осчастливить техподдержку. Им и так нелегко разгребать всё это.
#логгирование
🔥3❤1
Провальный ИПР
Сделать нормальный план индивидуального развития можно, если четко представляешь образ результата и можешь выразить его в конкретных компетенциях, которые тебе нужны. Плюс понимаешь что в твоем багаже полезного есть прямо сейчас, что надо добавить для достижения цели.
А потом ты берешь, и делаешь то что запланировано.
На прошлой неделе один менти-системный аналитик пришел ко мне закрывать свой ИПР. На старте мы обсуждали чему он должен научиться, как он должен это сделать, каких результатов добиться.
Это было плохо. Не то чтобы он вообще ничего не сделал — нет, человек явно приложил некоторые усилия. Возможно, даже значительные, — с его точки зрения. Но их оказалось ужасно недостаточно, чтобы изменить его состояние, как системы, для выхода на новый уровень «джун-мидл».
«Кому надо — тот и носится», такой важнейший совет я услышал от одного успешного бизнесмена и запомнил на всю жизнь. Я тогда спросил, почему он при том что имеет в наличии не один огромный бизнес, лично выясняет, в каком зале он читает лекцию и привозит проектор. Он объяснил, что принял ответственность прочитать эту лекцию, и теперь халатность организаторов не должна стать причиной её срыва. Ну, я был впечатлен. Мне тогда казалось, что такие важные люди делегируют всё (нет).
Важнее всего — делание. Создай активность и получи обратную связь. Совсем идиотизмом заниматься, конечно, не нужно. Но иметь на руках ИПР и ждать, что тебя будут вести и принуждать и пинать — не стоит.
Если есть сложности с самомотивациейто сидите и ничего не делайте то возможно, вы копаете не в ту сторону; может быть стоит уточнить, чего хочется на самом деле.
Встречайтесь со своим ментором и просите обратную связь в процессе ИПР. Может быть, вам знаком этот кошмарный опыт из школы или универа, когда весь семестр не ходил к научнику, а потом в конце надо сдавать и это леденящее понимание что не сдашь? Оно регулярно пытается повториться и на проектах (у меня прям ща один заказчик пытается такое устроить. Борюсь напалмом).
#жиза
Сделать нормальный план индивидуального развития можно, если четко представляешь образ результата и можешь выразить его в конкретных компетенциях, которые тебе нужны. Плюс понимаешь что в твоем багаже полезного есть прямо сейчас, что надо добавить для достижения цели.
А потом ты берешь, и делаешь то что запланировано.
На прошлой неделе один менти-системный аналитик пришел ко мне закрывать свой ИПР. На старте мы обсуждали чему он должен научиться, как он должен это сделать, каких результатов добиться.
Это было плохо. Не то чтобы он вообще ничего не сделал — нет, человек явно приложил некоторые усилия. Возможно, даже значительные, — с его точки зрения. Но их оказалось ужасно недостаточно, чтобы изменить его состояние, как системы, для выхода на новый уровень «джун-мидл».
«Кому надо — тот и носится», такой важнейший совет я услышал от одного успешного бизнесмена и запомнил на всю жизнь. Я тогда спросил, почему он при том что имеет в наличии не один огромный бизнес, лично выясняет, в каком зале он читает лекцию и привозит проектор. Он объяснил, что принял ответственность прочитать эту лекцию, и теперь халатность организаторов не должна стать причиной её срыва. Ну, я был впечатлен. Мне тогда казалось, что такие важные люди делегируют всё (нет).
Важнее всего — делание. Создай активность и получи обратную связь. Совсем идиотизмом заниматься, конечно, не нужно. Но иметь на руках ИПР и ждать, что тебя будут вести и принуждать и пинать — не стоит.
Если есть сложности с самомотивацией
Встречайтесь со своим ментором и просите обратную связь в процессе ИПР. Может быть, вам знаком этот кошмарный опыт из школы или универа, когда весь семестр не ходил к научнику, а потом в конце надо сдавать и это леденящее понимание что не сдашь? Оно регулярно пытается повториться и на проектах (у меня прям ща один заказчик пытается такое устроить. Борюсь напалмом).
#жиза
👍11❤3🔥1
Любимое: путать теплое с мягким
Аналитикам важно различать цель и результат при проектировании ИТ-систем и написании инженерной документации. Это нужно уметь делать, чтобы принимать и успешно реализовывать правильные (достигающие целей) решения в условиях растущей неопределенности и сложности при ограниченных ресурсах.
Про (аналитить) это
#глоссарий
Аналитикам важно различать цель и результат при проектировании ИТ-систем и написании инженерной документации. Это нужно уметь делать, чтобы принимать и успешно реализовывать правильные (достигающие целей) решения в условиях растущей неопределенности и сложности при ограниченных ресурсах.
Про (аналитить) это
#глоссарий
🔥6
Оценка задач 🔮
Оценка задачи (или проекта) не гарантирует того, что специалист сделал декомпозицию и действительно продумал ход работы над ней.
Специфика оценки своей части аналитиками состоит в высокой неопределенности относительно существенной сложности системы. Мы тупо пытаемся угадать будущую сложность на основании опыта, внешних признаков, имеющихся обрывков информации.
Мне нравится конус неопределенности, который я позаимствовал у Натальи (которая подсмотрела у Сергея Нужненко). Помогает мне наглядно показать коллегам, чего стоит наша оценка.
Наблюдал ещё такой эффект: если за неточную оценку наказывать (хотя бы выговаривать) то спецы начинают перезакладываться и точность страдает. Плюс оценка в одно лицо по ощущениям довольно утомительное занятие.
В команде оцениваем коллективно (системными аналитиками) в дискуссии чтобы: (а) все смогли высказаться и указать на возможные проблемы/пути решения и (б) по одиночке не выгорали. Ну и да, пишем список примерных задач по оцениваемой фиче с детализацией, чтобы было понятно откуда оценка взялась.
Еще момент: не даю в оценку писать штуки типа «коммуникация со стейкхолдерами» 🙈 а призываю писать по существу задачи, функциональным блокам и артефактам. Напоминаю, что «встречи» и «переписка» являются частью процесса анализа и самостоятельной ценности в отрыве от задачи не представляют.
Иногда так и говорю: за письма заказчик не заплатит
Оценка задачи (или проекта) не гарантирует того, что специалист сделал декомпозицию и действительно продумал ход работы над ней.
Специфика оценки своей части аналитиками состоит в высокой неопределенности относительно существенной сложности системы. Мы тупо пытаемся угадать будущую сложность на основании опыта, внешних признаков, имеющихся обрывков информации.
Мне нравится конус неопределенности, который я позаимствовал у Натальи (которая подсмотрела у Сергея Нужненко). Помогает мне наглядно показать коллегам, чего стоит наша оценка.
Наблюдал ещё такой эффект: если за неточную оценку наказывать (хотя бы выговаривать) то спецы начинают перезакладываться и точность страдает. Плюс оценка в одно лицо по ощущениям довольно утомительное занятие.
В команде оцениваем коллективно (системными аналитиками) в дискуссии чтобы: (а) все смогли высказаться и указать на возможные проблемы/пути решения и (б) по одиночке не выгорали. Ну и да, пишем список примерных задач по оцениваемой фиче с детализацией, чтобы было понятно откуда оценка взялась.
Еще момент: не даю в оценку писать штуки типа «коммуникация со стейкхолдерами» 🙈 а призываю писать по существу задачи, функциональным блокам и артефактам. Напоминаю, что «встречи» и «переписка» являются частью процесса анализа и самостоятельной ценности в отрыве от задачи не представляют.
Иногда так и говорю: за письма заказчик не заплатит
👍4🔥1
Существенная Сложность (Essential Complexity) - сложность того, что делает система, сложность реализованных ею моделей, отражающих сложность реального мира, не зависящая от способа и деталей реализации. Сложность, порожденная решаемой проблемой, и ничто не может устранить или уменьшить её. Мы можем только управлять ею таким образом, чтобы минимизировать объем существенной сложности, рассматриваемой одновременно, до уровня, не превосходящего ограничения краткосрочной памяти человека.
— emacsway-log #глоссарий
1
Telegram
Jira Priority
Emojipack with 6 emoji for Telegram Premium subscribers.
Наглядность в коммуникациях
Рабочие сообщения в телеграме должны быть максимально информативны, чтобы экономить внимание получателей. Если вы работаете с задачами в Atlassian Jira, то рекомендую использовать кастомные эмодзи Jira Priority для указания приоритетов задач в сообщениях, например:
⬆️ Доработать фид для маркетплейсов
➡️ Добавить в мониторинг отслеживание robots.txt
Получатель может сразу оценить степень срочности указанной задачи не открывая собственно задачу.
Использование кастомных эмодзи, правда, требует платного аккаунта в телеге.
Всё это укладывается в парадигму «заботы о читателе», про которую хорошо рассказывает Максим Ильяхов в книге «Пиши, сокращай» и Ольга Лукинова в канале «Цифровой этикет».
Рабочие сообщения в телеграме должны быть максимально информативны, чтобы экономить внимание получателей. Если вы работаете с задачами в Atlassian Jira, то рекомендую использовать кастомные эмодзи Jira Priority для указания приоритетов задач в сообщениях, например:
Получатель может сразу оценить степень срочности указанной задачи не открывая собственно задачу.
Использование кастомных эмодзи, правда, требует платного аккаунта в телеге.
Всё это укладывается в парадигму «заботы о читателе», про которую хорошо рассказывает Максим Ильяхов в книге «Пиши, сокращай» и Ольга Лукинова в канале «Цифровой этикет».
Please open Telegram to view this post
VIEW IN TELEGRAM
1👍3 1
[2/x] Как сделать правильное логгирование
Начать нужно с прояснения целей логгирования:
(1) Информирование о переходе систем в нештатный режим: узнать о проблеме раньше клиента;
(2) Анализ причин возникновения нештатных ситуаций: что сломалось, воспроизвести и починить;
(3) Сбор информации для оптимизации систем: анализ времени выполнения операций, найти «медленные», которые можно оптимизировать (в т.ч. на межсистемном уровне).
Иногда бОльший акцент нужно сделать в пользу защиты от вторжений, анализа уязвимостей и так далее. Всё, что связано с информационной безопасностью, лучше прояснять с профильными специалистами.
Источники информации для логов
(1) Клиентское приложение — даже веб-страницы должны вести лог, например в консоль браузера, чтобы при случае было чего отправить в техподдержку (пример — Crashlytics, Sentry)
(2) Веб-сервер — обычно имеет свои логи наподобие access.log, error.log и другие. Тупо пишет запросы и ответы на них без учёта бизнес-логики.
(3) Приложение — нужно описывать требования, какие логи хотим иметь, в каком формате, события каких типов писать и сколько хранить. Здесь учитываем бизнес-логику и архитектуру, дополнительные требования и пожелания в части анализа данных.
(4) Базы данных — обычно имеют свои логи с разной степенью детализации. Есть текстовые, есть бинарные.
(5) Сетевое оборудование — файерволлы всех типов, прокси и прочее, обычно пишут свои логи.
Что писать в лог
Типы сообщений, которые вы можете писать в лог:
(1) Получение входящих, отправка исходящих запросов;
(2) Валидация модели данных и параметров запроса;
(3) Аутентификация и авторизация — успех и ошибки отдельно;
(4) Ошибки приложения: runtime-ошибки, проблемы с сетью, долгие запросы, сообщения от используемых библиотек;
(5) Старты и остановки сущности приложения;
(6) Применение алгоритмов бизнес-логики — что пересчитано, трансформировано в данных;
(7) Исполнение потенциально опасных SQL-запросов на INSERT, UPDATE и DELETE;
(8) Создание и экспирация токенов, разрешений, изменение прав доступа, ролевые назначения;
(9) Отдельно логгировать действия пользователей с высокими административными полномочиями;
(10) Действия, потенциально опасные с юридической точки зрения: согласие пользователя на обработку персональных данных, согласование сертификатов между системами, подтверждение Terms of Use и так далее.
Возможно, стоит так же логгировать:
(11) Дерево ошибок — если позволяет стек приложения. Вся цепочка вызовов, приведшая к исключению, вместе со значениями параметров в вызванных методах, с указанием файла и строки в коде;
(12) Интенсивное использование какого-либо ресурса, превышающего пороговые значения, всё что похоже на DDOS, в том числе от корпоративных, внутренних систем;
(13) Подробный аудит изменяемых сущностей;
(14) Выявленные попытки фрода, подлога, подозрительного поведения определяемые логикой приложения;
(15) Изменение конфигурационных настроек приложения;
(16) Изменение версии приложения.
Что точно писать в лог не нужно
🔵 Пароли, токены, закрытые ключи
🔵 Database connection string
🔵 Номера банковских карт
🔵 Информацию, составляющую коммерческую тайну
🔵 Информацию, которая может быть признана незаконной для хранения — персональные данные, к примеру
Представьте, что судебные приставы изымут логи системы по решению суда и опубликуют их на сайте суда как часть материалов дела. Убрать их оттуда будет крайне проблематично. Сразу проектируйте так, чтобы подобный сценарий не стал для вас проблемой.
Как именно писать лог
Структура записи лога должна быть машиночитаемой и индексируемой. Формат данных зависит от хранилища. Одна из хорошо зарекомендовавших себя структур состоит из 4 частей — WWWW: when, where, who and what.
🔵 When — когда: дата-время, идентификаторы trace_id;
🔵 Where — где: название приложения, версия, эндпоинт, файл, модуль, компонент;
🔵 Who — кто: человек или система, адрес источника запроса, порты, идентификаторы;
🔵 What — что: тип и важность события, описание, параметры.
Для себя использую шаблон «Пример требований к логгированию», который дополняю в зависимости от специфики проекта.
#логгирование
Начать нужно с прояснения целей логгирования:
(1) Информирование о переходе систем в нештатный режим: узнать о проблеме раньше клиента;
(2) Анализ причин возникновения нештатных ситуаций: что сломалось, воспроизвести и починить;
(3) Сбор информации для оптимизации систем: анализ времени выполнения операций, найти «медленные», которые можно оптимизировать (в т.ч. на межсистемном уровне).
Иногда бОльший акцент нужно сделать в пользу защиты от вторжений, анализа уязвимостей и так далее. Всё, что связано с информационной безопасностью, лучше прояснять с профильными специалистами.
Источники информации для логов
(1) Клиентское приложение — даже веб-страницы должны вести лог, например в консоль браузера, чтобы при случае было чего отправить в техподдержку (пример — Crashlytics, Sentry)
(2) Веб-сервер — обычно имеет свои логи наподобие access.log, error.log и другие. Тупо пишет запросы и ответы на них без учёта бизнес-логики.
(3) Приложение — нужно описывать требования, какие логи хотим иметь, в каком формате, события каких типов писать и сколько хранить. Здесь учитываем бизнес-логику и архитектуру, дополнительные требования и пожелания в части анализа данных.
(4) Базы данных — обычно имеют свои логи с разной степенью детализации. Есть текстовые, есть бинарные.
(5) Сетевое оборудование — файерволлы всех типов, прокси и прочее, обычно пишут свои логи.
Что писать в лог
Типы сообщений, которые вы можете писать в лог:
(1) Получение входящих, отправка исходящих запросов;
(2) Валидация модели данных и параметров запроса;
(3) Аутентификация и авторизация — успех и ошибки отдельно;
(4) Ошибки приложения: runtime-ошибки, проблемы с сетью, долгие запросы, сообщения от используемых библиотек;
(5) Старты и остановки сущности приложения;
(6) Применение алгоритмов бизнес-логики — что пересчитано, трансформировано в данных;
(7) Исполнение потенциально опасных SQL-запросов на INSERT, UPDATE и DELETE;
(8) Создание и экспирация токенов, разрешений, изменение прав доступа, ролевые назначения;
(9) Отдельно логгировать действия пользователей с высокими административными полномочиями;
(10) Действия, потенциально опасные с юридической точки зрения: согласие пользователя на обработку персональных данных, согласование сертификатов между системами, подтверждение Terms of Use и так далее.
Возможно, стоит так же логгировать:
(11) Дерево ошибок — если позволяет стек приложения. Вся цепочка вызовов, приведшая к исключению, вместе со значениями параметров в вызванных методах, с указанием файла и строки в коде;
(12) Интенсивное использование какого-либо ресурса, превышающего пороговые значения, всё что похоже на DDOS, в том числе от корпоративных, внутренних систем;
(13) Подробный аудит изменяемых сущностей;
(14) Выявленные попытки фрода, подлога, подозрительного поведения определяемые логикой приложения;
(15) Изменение конфигурационных настроек приложения;
(16) Изменение версии приложения.
Что точно писать в лог не нужно
Представьте, что судебные приставы изымут логи системы по решению суда и опубликуют их на сайте суда как часть материалов дела. Убрать их оттуда будет крайне проблематично. Сразу проектируйте так, чтобы подобный сценарий не стал для вас проблемой.
Как именно писать лог
Структура записи лога должна быть машиночитаемой и индексируемой. Формат данных зависит от хранилища. Одна из хорошо зарекомендовавших себя структур состоит из 4 частей — WWWW: when, where, who and what.
Для себя использую шаблон «Пример требований к логгированию», который дополняю в зависимости от специфики проекта.
#логгирование
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥5
Системный сдвиг
Сколько вы знаете способов передачи данных на клиент по инициативе сервера?
Этот пост зацепил моё внимание заявленной темой — но по прочтению у меня сложилось впечатление, что с логикой изложения что-то не то. Задал вопрос автору в каментах и продублирую его здесь.
Юрий Куприянов ведет довольно интересный для меня канал, но иногда возникает ощущение что логика сохраняется в локальных утверждениях, но цельность всего поста будто бы чуток «троит» 😈
===
Всю статью будто бы пронизывает трудноуловимый сбой в логике повествования. Прошу прощения у автора, возможно я неверно интерпретировал некоторые утверждения в заметке.
(1) В заголовке постулируется тема по передаче данных от сервера к клиенту по инициативе сервера; к концу статьи множество понятий сваливается в кучу, включая event-driven архитектуру и логику принятия решений на уровне приложения.
Возможно я ошибаюсь, но решение о том, вокруг чего «устроены сообщения», должен принять проектировщик при проектировании системы, а не «приложение на уровне логики».
(2) Мне кажется неверно постулировать использование «оберток» GraphQL и gRPC вокруг коммуникационных протоколов по причине того, что «сложно разобраться» с этими самыми коммуникационными протоколами HTTP/* и WebSocket.
Создавались GraphQL и gRPC чтобы решить вполне конкретные проблемы:
GraphQL — язык запросов, чтобы решить проблему поставки рекурсивных данных в условиях узких каналов передачи данных;
gRPC — фреймворк, чтобы связать большое количество микросервисов написанных на разных языках в корпоративном контуре, используя преимущества протоколов SPDY, HTTP/2 и QUIC.
Выбор в пользу технологии должен делаться системно, с рассмотрением решаемых проблем и с учетом архитектуры информационных систем. Не потому, что технология сложная.
(3)
REST предлагался Филдингом как концепция «самоописываемого состояния гипермедиа» в условиях «анархического масштабирования сети». Основная идея состояла в том, что клиент может добраться до любого узла графа API, начав от корня и следуя ссылкам HATEOAS. В целом можно почитать комментарий Филдинга здесь или разбор диссертации Филдинга здесь.
Как архитектурный стиль REST API может стать более или менее технологическим? Да, REST вовсе не требует использования HTTP для имплементации. Но в чём именно может выражаться меньшая технологичность этого стиля?
Тот же вопрос применим и к RPC.
Буду признателен за содержательные ответы или критику.
===
Юрий обещал ответить содержательно. Записал в книжку душных напоминаний😯
Юрий Куприянов ведет довольно интересный для меня канал, но иногда возникает ощущение что логика сохраняется в локальных утверждениях, но цельность всего поста будто бы чуток «троит» 😈
===
Всю статью будто бы пронизывает трудноуловимый сбой в логике повествования. Прошу прощения у автора, возможно я неверно интерпретировал некоторые утверждения в заметке.
(1) В заголовке постулируется тема по передаче данных от сервера к клиенту по инициативе сервера; к концу статьи множество понятий сваливается в кучу, включая event-driven архитектуру и логику принятия решений на уровне приложения.
Возможно я ошибаюсь, но решение о том, вокруг чего «устроены сообщения», должен принять проектировщик при проектировании системы, а не «приложение на уровне логики».
(2) Мне кажется неверно постулировать использование «оберток» GraphQL и gRPC вокруг коммуникационных протоколов по причине того, что «сложно разобраться» с этими самыми коммуникационными протоколами HTTP/* и WebSocket.
Создавались GraphQL и gRPC чтобы решить вполне конкретные проблемы:
GraphQL — язык запросов, чтобы решить проблему поставки рекурсивных данных в условиях узких каналов передачи данных;
gRPC — фреймворк, чтобы связать большое количество микросервисов написанных на разных языках в корпоративном контуре, используя преимущества протоколов SPDY, HTTP/2 и QUIC.
Выбор в пользу технологии должен делаться системно, с рассмотрением решаемых проблем и с учетом архитектуры информационных систем. Не потому, что технология сложная.
(3)
«кажется, всё идёт к тому, что стили API (REST или RPC) будут больше логическими, а не технологическими»
REST предлагался Филдингом как концепция «самоописываемого состояния гипермедиа» в условиях «анархического масштабирования сети». Основная идея состояла в том, что клиент может добраться до любого узла графа API, начав от корня и следуя ссылкам HATEOAS. В целом можно почитать комментарий Филдинга здесь или разбор диссертации Филдинга здесь.
Как архитектурный стиль REST API может стать более или менее технологическим? Да, REST вовсе не требует использования HTTP для имплементации. Но в чём именно может выражаться меньшая технологичность этого стиля?
Тот же вопрос применим и к RPC.
Буду признателен за содержательные ответы или критику.
===
Юрий обещал ответить содержательно. Записал в книжку душных напоминаний
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3 2
Шина vs Брокер
Вчера выступили на митапе «Шина vs Брокер» в ITFB вместе с Наташей @start_in_IT. Рассказали аналитикам, Q&A, разработчикам и руководителям проектов что это такое, чем различается и где применяется. Несмотря на то, что был вечер, удалось вовлечь ребят в проектирование выдуманной системы — пусть и в урезанном варианте, но всё же настоящее проектирование и рассуждения о том, какой способ интеграции выбрать и главное, почему именно такой.
В реальной жизни откровенно ошибочные варианты бывают редко. Обычно архитекторы и команда выбирают решение учитывая множество критериев: функциональные и нефункциональные требования, ограничения существующего ландшафта. Идёт сравнение «за» и «против» разных вариантов, взвешивание рисков, стоимости поддержки и ещё триллиона вещей. Иногда тупо решает политика; тогда инженеры пожимают плечами и готовятся разгребать последствия.
На митапе коллеги серьёзно подошли к вопросу и многие смогли неплохо аргументировать свои решения.
Мне понравилось🕶 и спасибо коллегам за приглашение!
Подумываю поучаствовать где-нибудь, а может быть даже организовать архитектурные ката:
Почитать про них можно на английском или на русском.
Вчера выступили на митапе «Шина vs Брокер» в ITFB вместе с Наташей @start_in_IT. Рассказали аналитикам, Q&A, разработчикам и руководителям проектов что это такое, чем различается и где применяется. Несмотря на то, что был вечер, удалось вовлечь ребят в проектирование выдуманной системы — пусть и в урезанном варианте, но всё же настоящее проектирование и рассуждения о том, какой способ интеграции выбрать и главное, почему именно такой.
В реальной жизни откровенно ошибочные варианты бывают редко. Обычно архитекторы и команда выбирают решение учитывая множество критериев: функциональные и нефункциональные требования, ограничения существующего ландшафта. Идёт сравнение «за» и «против» разных вариантов, взвешивание рисков, стоимости поддержки и ещё триллиона вещей. Иногда тупо решает политика; тогда инженеры пожимают плечами и готовятся разгребать последствия.
На митапе коллеги серьёзно подошли к вопросу и многие смогли неплохо аргументировать свои решения.
Мне понравилось
Подумываю поучаствовать где-нибудь, а может быть даже организовать архитектурные ката:
Это возможность в игровой форме потренировать свои архитектурные навыки на вымышленных проектах. Формат основан на Architectural katas — игре для разработчиков и архитекторов ПО.
Почитать про них можно на английском или на русском.
Please open Telegram to view this post
VIEW IN TELEGRAM
Please open Telegram to view this post
VIEW IN TELEGRAM
❤7🔥2
Как называть очереди в брокерах
Слава пришла откуда не ждали. Вчера во внутренней группе для аналитиков коллега поделился артефактом СА с таким комментарием:
Из любопытства я порылся в приложенном документе (закину в комментарии к посту) и обнаружил в нём копию своего собственного документа, который я создал на одном из проектов в 2022 году.
Неповторимый, так сказать оригинал вот он: Правила именования топиков
Создавайте правила
Мало просто правильно назвать очередь или грамотно описать артефакт. Создавайте правила, описывайте стили, внедряйте принципы организации информации. Тогда больше шансов, что команда будет работать как команда, а не просто группа случайно собранных людей, каждый со своим неповторимым почерком.
#брокеры
Слава пришла откуда не ждали. Вчера во внутренней группе для аналитиков коллега поделился артефактом СА с таким комментарием:
Зашёл я в Инстаграм значит, а там в рилсах вот такой шаблон девушка раздает. Некоторые примеры наивные, но в целом как чек-лист о чем нужно/можно подумать аналитику наверное неплохо
Из любопытства я порылся в приложенном документе (закину в комментарии к посту) и обнаружил в нём копию своего собственного документа, который я создал на одном из проектов в 2022 году.
Неповторимый, так сказать оригинал вот он: Правила именования топиков
Создавайте правила
Мало просто правильно назвать очередь или грамотно описать артефакт. Создавайте правила, описывайте стили, внедряйте принципы организации информации. Тогда больше шансов, что команда будет работать как команда, а не просто группа случайно собранных людей, каждый со своим неповторимым почерком.
#брокеры
👍13❤2 2