Рубрики
Без рубрики

Рефакторирование заросшего класса уведомлений в Джанго

Фото Раджеша Аппалла на UNSPLASH После работы с той же кодовой базой на некоторое время наступает … Tagged с рефакторингом, Django, Python, Technical.

Фотография Раджеш Аппалла на Неспособный

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

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

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

Начальное состояние

Это то, на что выглядел уведомление о отправке, перед рефактором:

Проблемы, которые я определил и хотел решить с рефактором:

Аргументы

  • Send_Notification принимает девять аргументов, не считая дополнительных аргументов ключевых слов, которые можно передавать (** Kwargs); Это срочно нужно улучшить, поскольку отладка этого метода чрезвычайно сложна. Попытка изолировать, какой конкретный аргумент, принятый в ошибке, или создает определенную часть текста в электронном письме, оказалась чрезвычайно трудоемкой в прошлом.

Журналы

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

Сложность

  • Код send_notificationmethod пытается сделать слишком много вещей, что делает его чрезвычайно запутанным.

Метод по существу отвечает за создание трех типов уведомлений:

  1. Объекты уведомления в базе данных (которые обслуживают уведомления Центра веб -приложений)
  2. Мобильные уведомления Push
  3. Электронные письма

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

Наследование

  • Просмотреть классы наследуют от sendnotificationmixin. Посмотреть классы не являются классами уведомлений, поэтому наследство не имеет смысла в этом сценарии. Это будет заменено композицией. Несмотря на редкое, было пару раз, когда наследство вызывало перезаписывание метода.

Аргументы (снова)

  • Send_Notification необходимо вызвать с очень специфическим набором аргументов. Их творение занимает много строк кода внутри методов класса View. Они добавляют шум и беспорядок к представлениям и будут заменены вызовом методу из SendNotificationMixin, который будет знать, как отправить надлежащие уведомления для события, созданного в этой точке.

Спектакль

  • Производительность – большая проблема для событий, которые требуют, чтобы многие уведомления были отправлены, например, если консультант создает новую задачу и назначает ее 100 студентам. Из моего тестирования проблема вызвана как путем уведомления о отправке кода, так и фактическими вызовами, сделанными внешними услугами. Решение будет двумя протечками: для уведомления, отправляющего код, рефактор также будет сосредоточен на сокращении сложности времени кода; Для звонков по электронной почте и уведомления о отправке уведомлений они будут перемещены в каналы Джанго, асинхронный процессор задач.

Чрезмерно большой объект

  • Весь объект запроса Django передается из методов просмотра вплоть до метода отправки электронной почты, чтобы использовать только некоторые из своих свойств в некоторых методах. Помимо того, что он является ненужным, чтобы отправлять весь объект только для некоторых свойств, это также вызывает проблему для событий, которые запускают уведомления за пределами вызовов API, где нет HTTP -запроса для прохождения.

Наследство (снова)

  • Класс наследует от SendEmailMixin. Хотя может быть представлен аргумент о том, является ли уведомление, отправляющее класс, является типом класса отправки электронной почты (и, следовательно, наследство было бы подходящим решением), SendNotificationMixin не использует ни одно из принесенных пособий, которое приносит наследство. Пока единственным методом вызовы классов уведомлений от Sendemailmixin является send_email, композиция имеет больше смысла. Это также поможет очистить больше классов просмотра, которые наследуют от класса отправки электронной почты.

Стандартизация (или ее отсутствие)

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

Фаза 1

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

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

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

Я повторил этот шаг для всех других классов представления и создал 22 новых метода на SendNotificationMixin, которые обрабатывают создание уведомлений на основе конкретных событий.

Фаза 2

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

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

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

context = {
            'invitee': invitee,
            'link': the_right_host(request)
}

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

context = {
            'invitee': invitee,
            'link': settings.HOST_URL
}

При этом изменении Send_email больше не требует запроса, что означает, что send_notification также больше не требует запроса. Это позволяет нам избавиться от этого объекта повсюду в базе кода, что приводит к массовому PR с 1379 измененными линиями, 311 из них полностью удален. Удаление кода чувствует себя Хорошо 😁.

Оригинал: “https://dev.to/gabivoicu/refactoring-an-overgrown-notifications-class-in-django-4m4h”