Red Collar | DEV
961 subscribers
234 photos
11 videos
129 links
Про разработку от команды Red Collar
redcollar.ru

Основной канал Red Collar @rdclr_home
Download Telegram
MapStruct
Сегодня утром я проводил код-ревью нашего java-стажера и заметил участок кода, который можно автоматизировать.

В разработке Spring-based приложений зарекомендовал себя подход разделения приложения на «слои» — Controller -> Service -> Repository (в базовом представлении). При его использовании важно следить, чтобы нижний слой не имел доступа к слою выше. Наших данных это тоже касается и, если в слое контроллеров у нас участвуют сущности БД, то это считается плохим тоном и требуется проводить рефакторинг. Тут нам на помощь приходят DTO (Data Transfer Object), в которые мы заносим данные из наших сущностей и оперируем уже ими.

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

Ссылка на библиотеку — https://mapstruct.org/

#rdclr_backend #java #library
CriteriaApi
Не раз мы сталкивались с задачами на фильтрацию какой-либо выборки данных по определенным параметрам, которые могут либо присутствовать, либо нет. Как же лучше всего реализовать данный фильтр?

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

Тут на помощь приходит CriteriaApi. Данный пакет инструментов позволяет динамически строить запрос в БД, оперируя объектами, а не самим SQL. Вдобавок к этому, Spring фреймворк предоставляет нам интерфейс Specification<T>, который упрощает взаимодействие с CriteriaApi. Пример работы приведен на картинке ниже.

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

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

Если Вам требуется возвращать не объект в респонсе, а какое-то представление (например, html), то можете воспользоваться @ControllerAdvise. Разница между ними такая же, как и между @Controller и @RestController. В итоге получаем единую точку обработки всех исключений, и если в приложении что-то случится, весь поток выполнения программы перейдет в RestControllerAdvise.

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

#rdclr_backend #java
Пример реализации
Ловушка @Transactional или использование Self-inject’ов
В бине имеется 2 метода: a() и b(), помеченных аннотацией @Transactional. Если мы из метода а() вызовем метод b() — как поведет себя транзакция метода b()?
Правильный ответ — транзакция метода b() не выполнится.

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

Почему же транзакция не выполнится? Дело в том, что когда мы делаем someService.callMethod() — вызывается метод Бина, а когда внутри a() дергаем b() — вызывается метод Класса, т.е. без каких-либо прокси-оберток Спринга и прочего. Именно из-за этого транзакция метода b() и не выполнится, потому что сам класс про неё ничего не знает.

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

#rdclr_backend #java
Нетоксичной выходной атмосферы всем в этом чатике!

#meme
Цикл Деминга-Шухарта — универсальный подход к ведению проекта и его непрерывному улучшению.

Цикл Деминга-Шухарта, или Цикл PDCA — известная модель непрерывного улучшения процессов, получившая название цикла Шухарта-Деминга или цикла PDCA, применение которой в самых различных областях деятельности позволяет эффективно управлять этой деятельностью на системной основе. Цикл состоит из 4 этапов.

Планирование (Plan) — разберитесь, почему что-то не получается, в чём проблема. На этом этапе необходимо сформулировать цель, а также выяснить, к какому результату стремитесь и какие методы помогут в его достижении. Для этого составляется так называемые action план или план действий.
|
Реализация (Do) — работайте согласно новому плану и не нарушайте его условия.
|
Проверка (Check) — этот этап продразумевает проверку полученных результатов и их исследования. Необходимо понять куда мы движемся. Процесс становится лучше или хуже, и в чем причины этого.
|
Действие (Action) — здесь необходимо исправить ошибки. Если нужно, то внести изменения в требования и сам процесс.

Цикл Деминга не имеет конца, это постоянный цикл улучшения процесса разработки ПО.

#rdclr_QA #product
Всем привет! Меня зовут Максим. В компании Red Collar я занимаю позицию QA инженера. На этой неделе поговорим немного о качестве ПО.
Разберем принципы менеджмента Э. Деминга — первые 7

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

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

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

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

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

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

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

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

🤝 7. Новые методы руководства. Руководитель — учитель, а не надзиратель.
Если руководитель тратит свое время на жесткий контроль подчиненных, это прямо свидетельствует о низких стандартах качества. Менеджмент будет сам себя вводить в заблуждение, что недобросовестное отношение рабочих к делу — причина низкого качества. Необходимо создать такую среду, в которой люди буду заинтересованы в своей работе. Однако часто можно видеть противоположную картину. Условия принуждают человека выполнять свое дело плохо, и он тогда теряет интерес к работе, что приводит к более низком качеству.

#rdclr_QA #product
Принципы менеджмента Э. Деминга, продолжение цикла, 8-14.

В целом, рекомендую к прочтению его полную книгу «Выход из кризиса». Она поможет в освоении новой философии менеджмента через отказ от традиционных методов. Но для скорости продолжаю (и заканчиваю) выжимку принципов, которые вынес из ее.

🖤 8. Доверие (отказ от управления, основанного на страхе).
Для улучшения процессов важно рассматривать любые идеи. Однако часто взаимодействие построено таким образом, что сотрудник испытывает страх перед руководителем, особенно если в команде активно используется система штрафов. Например, член команды может предложить какие-либо меры по улучшению и ускорению процессов, так как он работает над техническими задачами каждый день, в отличие от руководителя. Не следует отвергать его предложения, ведь они могут сократить издержки и принести огромную пользу для команды.

🔓 9. Разрушайте барьеры между подразделениями.
Люди из различных подразделений — аналитики, разработчики, тестировщики, менеджеры должны работать в командах, чтобы устранять проблемы, которые возникают в процессе разработки ПО.

🔦 10. Откажитесь пот пустых призывов, требующих бездефектной работы, но не сообщающих о методах её достижения.
Такие призывы вызывают лишь брезгливое отношение; основная масса проблем низкого качества и производительности связана с системой, и поэтому их решения находятся за пределами рядовых сотрудников.

🧮 11. Откажитесь от количественных оценок работы.
Если система, в которой вы работаете, стабильна, нет нужны определять цель повышения производительности и качества в цифрах — все равно вы получите только то, что может дать сама система. Если система нестабильна, то снова нет смысла определять цель в цифрах, поскольку нет возможности узнать, что выдаст система — о ее возможностях нельзя сказать. А значит, запланированная цель, скорее всего, не будет достигнута. Управление, которое основано на количественных показателя, — это попытка управлять, не зная, что нужно сделать.

👨🏻‍💻 12. Устраните барьеры, которые не позволяют людям гордиться своей квалификацией.
Это предполагает, помимо всего прочего, отказ от ежегодных аттестаций и методов управления целями. И снова обязанности менеджеров должны быть перенесены с достижений чисто количественных показателей — на качественные.

🧠 13. Поощряйте стремление к образованию и самосовершенствование сотрудников. Вызовите у сотрудника интерес к самосовершенствованию. Например, нельзя игнорировать стремление сотрудника посетить какие-то конференции. Обмен опытом пойдет на пользу не только сотруднику, но и компании.

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

#rdclr_QA #product
«5 почему». Поиск причин проблемы.

Метод «5 почему» заключается в том, чтобы докопаться до сути проблемы. Нужно задать вопрос, начав со слова «почему», и получить ответ, после чего переформулировать полученный ответ в новый вопрос, добавив к нему «почему».

🧶 Пример:
1. Почему мы не отправили новостную рассылку?
— Потому что релиз не был сделан вовремя.
2. Почему релиз не был сделан вовремя?
— Потому что разработчики все еще работают над новыми фичами.
3. Почему они все еще работают над новыми фичами?
— Один из новых разработчиков не знает регламентов.
4. Почему новый разработчик не знает регламентов?
— Он не был обучен должным образом.
5. Почему он не был обучен должным образом?
— Потому что его руководитель считает, что новых сотрудников не нужно тщательно обучать, и они должны учиться во время работы.

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

Таким образом, метод «5 почему» направлен на глубокое изучение определенной проблемы до тех пор, пока не будет найдена настоящая причина.

Главная особенность и преимущества метода — простота. Пять — это среднее число, достаточное для получения ответа. Но у вас может быть и три, и двадцать вопросов.
#rdclr_QA #product
Привет, меня зовут Артем, я frontend-разработчик компании Red Collar, и на этой неделе предлагаю немного поговорить о концепциях доступности веб-интерфейсов. Расскажу, почему это важно для проекта, а также с чего начать погружение в эту сложную и многогранную тему.

#rdclr_frontend
Инклюзивность и доступность веб-интерфейсов

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

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

Как добиться повышения доступности интерфейса

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

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

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

#rdclr_frontend
Семантические элементы в доступности интерфейсов

К сожалению, сегодня по-прежнему приходится говорить об очевидных вещах вроде: «Используйте семантическую разметку», «Не забывайте альтернативные тексты для картинок» и все в таком духе. Спецификация HTML5 вышла 7 лет назад, но ряд разработчиков в своем коде до сих пор не применяют или применяют неверно теги header, nav, section, main и т. д.

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

🌳Дерево доступности
Современные браузеры наряду с DOM-моделью создают на ее основе так называемое дерево доступности (accessibility tree, AOM), которое будет содержать информацию о «доступности» элемента: у каждого объекта будет имя, описание, роль и состояние. Затем браузер предоставляет эту модель вспомогательным программам, например, скринридерам.

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

👨‍💻Пример дерева доступности
Продемонстрирую на маленьком сэмпле html-кода, как браузер строит дерево доступности: перед нами обычная группа радио-кнопок в форме (для примера будет форма оплаты), все элементы нативные и имеют текстовые ноды, поэтому браузер может построить дерево в котором будет выделена группа, ее название, члены группы, при этом он видит, что внутри label’ов есть radiobutton’ы, а значит это интерактивные элементы, имеющие свои состояния.

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

#rdclr_frontend
Focus on me: навигация с клавиатуры

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

🔦 Любой интерактивный элемент в интерфейсе, будь то кнопка, ссылка или поле для ввода, должен реагировать на фокус. То есть, во-первых, он должен так или иначе «подсвечиваться» при получении фокуса (когда вы нажимаете Tab или Shift+Tab).

⌨ Во-вторых, он должен реагировать на нажатие Enter и Space точно так же, как если бы вы кликнули по нему (и не должен, если имеет состояние disabled). А если предусмотрено какое-то поведение при наведении на элемент, то и оно должно воспроизводиться: либо при получении фокуса, либо при нажатии на Enter и Space, когда элемент получил фокус.

📇 В-третьих, важно, чтобы порядок переключения фокуса отражал порядок, в котором мы видим интерактивные элементы на экране. Кроме того, на странице могут быть скрытые слои (temporality offscreen): дропдаун-меню, поп-апы, модальные окна и проч., – и в них часто бывают интерактивные (focusable) элементы. До тех пор, пока элемент скрыт, он не должен получать фокус при навигации с клавиатуры.

📸 В-четвертых, сбрасывайте состояние фокуса в SPA-приложениях после перехода по ссылкам. При навигации по разделам SPA-сайта, предыдущее состояние фокуса может не измениться, если активный элемент не был перерисован. В результате, после перехода в новый раздел, скринридер продолжит воспроизводить контент с того места, на котором остановился. Нужно «перебросить» фокус в начало документа, то есть на первый focusable-элемент на странице.

#rdclr_frontend
Как достичь корректной работы приложения с клавиатуры

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

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

Да, в современных интерфейсах часто встречаются сложные объекты для ввода (дейт-пикеры, мульти-селекты etc.), которые нельзя полностью реализовать нативными средствами. В этом случае вам следует позаботиться о том, чтобы элементы «не проваливались» при работе с клавиатуры.

📸 2. Обрабатывайте состояние focus с помощью css и javascript. Опишите стилистические правила для состояний focus, disabled и проч., как именно это будет реализовано — с помощью outline, box-shadow или иными средствами — не важно. Для простых элементов этого будет достаточно.

В отдельных случаях (например, чтобы показать выпадающее меню) обрабатывайте события focus и blur при помощи javascript.

📇 3. Следите за порядком элементов в DOM или определяйте порядок, в котором элементы будут перебираться при помощи Tab, используя атрибут taborder.

🥅 4. Для фокус-менеджмента применяйте стратегию focus trapping. В общем виде это может выглядеть так: на странице есть поп-ап, фокус на нем должен быть заблокирован. При его открытии делаем наоборот: элементы вне поп-апа должны быть заблокированы для фокуса, а сам поп-ап разблокирован.

Иногда для этого приходится написать много кода, который будет обрабатывать focusable-элементы в поп-апе и за его пределами. Решением этой проблемы может стать атрибут inert, позволяющий выключать видимость элементов для скринридеров и блокировать фокусировку на них. На сегодняшний день это поддерживается не везде, но вы можете использовать Inert Polyfill или реализовать нечто похожее самостоятельно.

#rdclr_frontend