В Академии Selectel появился бесплатный курс «Погружение в компьютерные сети». Он поможет разобраться в принципах работы, понять ключевые термины и уверенно ориентироваться в основах. Всего час — и сложные вещи станут простыми.
Курс подходит новичкам, которые хотят разобрать тему по полочкам. Но и опытным специалистам будет полезно: с этими материалами вы восполните пробелы в знаниях и вспомните все, что забылось со временем.
Начните обучение в Академии Selectel прямо сейчас ➡️
ОТП Банк дважды стал лауреатом премии Finnext 2025
ОТП Банк стал двукратным лауреатом премии Finnext 2025. Итоги подвели 27 марта в Москве. В рамках этого престижного события, учрежденного ИД «Регламент» и порталом FutureBanking, банк был признан победителем в двух ключевых номинациях: «Лучший кейс в технологиях работы с данными банка» и «Лучший кейс инноваций в маркетинге банковских продуктов».
Лучший кейс инноваций в маркетинге банковских продуктов
Награда была присуждена ОТП Банку за лучший кейс инноваций в маркетинге банковских продуктов. Проект по AI персонализации для холодного трафика на сайте банка позволил значительно улучшить взаимодействие с клиентами.
Используя платформу Sales Ninja, ОТП Банк перешел от ручных A/B тестов к автоматическим предиктивным персонализациям на основе искусственного интеллекта, что позволяет в режиме реального времени подстраивать сайт под каждого пользователя. Даже если он зашел на сайт в первый раз.
«Мы смогли не только «пробить потолок» классических подходов к работе над сайтом, но и улучшить ценность для наших клиентов. Персонализация — это не только про метрики, но и про то, что мы говорим с клиентом на понятном для него языке», — подчеркнул Вадим Валиуллин, product owner сайта ОТП Банка.
Лучший кейс в технологиях работы с данными банка
Проект «Data Governance: управление данными как активом в ОТП Банке» направлен на совершенствование культуры работы с данными. Николай Шевцов, директор по управлению данными ОТП Банка, отметил, что «данные в банке теперь воспринимаются как стратегический актив, а управление ими стало частью корпоративной культуры».
За последний год команда внедрила систему Data Governance и интегрированную с ней платформу автоматизированного контроля качества данных с элементами AI, обучила более 400 сотрудников работе с ней и интегрировала стандарты безопасности данных на всех уровнях организации. Результатом стало снижение ошибок при формировании отчетности, повышение доверия к качеству данных и улучшение процесса принятия бизнес-решений.
Он пояснил, что проект по внедрению культуры Data Governance играет ключевую роль в повышении эффективности, прозрачности и конкурентоспособности банка. «Глубокий анализ качественных клиентских данных позволяет персонализировать продукты и услуги, снижается вероятность ошибок в расчетах. А это значит, что коммуникации и предложения для клиентов становятся максимально индивидуальными», - подчеркнул Николай Шевцов.
К рекламе на сайтах все давно привыкли. Наверное, все так же понимают, что рекламные баннеры - это способ заработка для сайта, поэтому просьбы "отключите пожалуйста блокировщик" - это вполне понятно.
Но почему на некоторых сайтах, не будем ни на кого показывать пальцем, простая операция блокировки рекламы не только убирает какие-то там дополнительные картинки, которые можно было бы считать элементом дизайна и даже украшением - но еще и снижает загрузку CPU примерно в 8 раз?
Это что, показ картинки НАСТОЛЬКО процессор грузит? Какая-нибудь игра типа Quake c "живой" графикой - и то меньше ресурсов жретъ. Или её попиксельно рисуют джваскриптом? Или это не в картинке проблема?
А что, если (ну так, в порядке предположения) владельцы вебсайтов посмотрят внимательнее, что и как там у них работает, и будут просто показывать рекламные картинки без всех этих прилагающихся к ним тормозов и жора памяти - может быть тогда люди будут меньше пользоваться всякими адблокерами?
Или эту мысль надо доносить до рекламодателей, в лице их SMM-щиков?
Регулярно на Хабре выходят статьи с рекомендацией использовать moment.js. В комментариях обязательно начинают советовать какой-нибудь dayjs или js-joda, но не потому, что они чем-то сильно лучше, а потому, что первый задепрекейчен авторами.. в пользу luxon.
Что за мания такая у JS-еров использовать раздутые тормозные библиотеки? Есть же быстрый и миниатюрный $mol_time с гораздо более удобным и функциональным API, почти полностью поддерживающим ISO8601, в отличие от всех остальных библиотек.
Бенчмарки говорят сами за себя
Что мотивирует людей довольствоваться не самым лучшим решением в индустрии? Я, наверно, странный, но я не могу этого понять.
Удалось за вечер написать расширение под VS Code, которое на onSave траспайлит псевдокод (так называемый sketch код) и сохраняет. Пока это POC и не полностью автоматизированный, но в качестве теста уже интересно
Представлен оналайн‑ресурс под названием «Утраченное искусство логарифмов», в котором исследуется полезность, история и повсеместность этого чудесного изобретения, логарифмы, включая то, что они, такое; с некоторыми демонстрациями их основного исторического применения в плоской и сферической тригонометрии.
Проект находится в разработке, но там уже есть основные начальные главы.
Как не надо использовать Assert, если реализуете подход Design by Contract
Использовать Assert вместо if err != nil { return err}
Одно из неправильных применений Assert — это замена им проверки, которая действительно должна быть и на которую нужно реализовать реакцию в коде.
Выполнять вычисления при вызове Assert
Еще одна распространенная и трудно выявляемая ошибка — это выполнение вычислений и присваивание значений переменным прямо при вызове Assert, которые могут быть упразднены при оптимизации кода компилятором:
e.g. Assert(i++ > 0, “осторожно, не факт, что в релизе i увеличится”),
Assert(call_to_f1(), “осторожно, не факт, что call_to_f1() будет вызвана в релизе”).
Удалять Assert, несмотря на то, что это часть описания контракта
Непонимание, что Assert — это реализация контракта, может привести к тому, что разработчик, незнакомый с DbC, захочет просто удалить проверку. Однако нужно всегда помнить, что срабатывание Assert говорит о нарушении контракта одной из сторон. То есть, если срабатывает Assert, надо прежде всего найти баг и пофиксить. А уж если контракт действительно должен быть изменен, Assert подскажет, где находятся участки кода, на которые нужно обратить внимание.
Например, вызывающая сторона может полагаться на некоторое поведение вызываемого кода. И если вызываемый код существенно изменился и контракт не выполнен, то вызываемая сторона тоже должна быть существенно переосмыслена.
В реализации пакета Go 1.23 fmt-функция Printf всегда возвращает err = nil. И практически все игнорируют возвращающееся значение ошибки, тогда как могли бы проверять постусловие assertion.Assert (err == nil). Так, рано или поздно в последующих версиях можно научить код реагировать на err, отличный от nil.
Как правильно применять assertions, если реализуете подход Design by Contract для улучшения производительности кода в продакшене? Читайте в статье →
Собственные макеты вывода для пользовательских полей Joomla
Мы привыкли использовать механизм переопределения макетов Joomla: скопируй нужный тебе файл макета в папку html шаблона и твори там что хочешь. Это в полной мере относится и к пользовательским полям Joomla.
Joomla ищет макеты рендера всех пользовательских полей в следующем порядке:
Есть ли файл templates/[template name]/html/layouts/[component name]/fields/render.php , переопределяющий макет вывода полей для конкретного компонента? Да - используем его.
Нет? Есть ли файл components/[component name]/layouts/fields/render.php в папке компонента? Да - используем его.
Нет? Есть ли файл templates/[template name]/html/layouts/com_fields/fields/render.php, переопределяющий вывод полей для com_fields? Да - используем его.
Нет? Используем файл components/com_fields/layouts/fields/render.php Это механизм поиска переопределений файлов макетов.
Вчера столкнулся с тем, что если поле вставлено в текст материала с помощью шорт-кода (кнопкой редактора) вида {field 25}, то переопределения не сработали. Поэтому стал вспоминать как сделать свой макет для поля Joomla.
Выбор пользовательского макета для рендера поля Joomla
Файл components/com_fields/layouts/field/render.php копируем в templates/YOUR_TEMPLATE/html/layouts/com_fields/field/etapy-raboty-nad-proektom.php. Обратите внимание, что мы файл переименовали, чтобы в настройках поля видеть его в выпадающем списке. После этого всё заработало как надо.
Благо, переводил уже раньше статью Как происходит рендер пользовательских полей в Joomla?. Потом, порывшись по своему же переводу увидел, что эта особенность работы Joomla в статье уже в ней описана 😂. А также напомнил себе о возможности указывать макет поля прямо в шорт-коде, через запятую: {field 25,etapy-raboty-nad-proektom}.
— Да, фронтенд перенасыщен. Фреймворков много, технологии постоянно меняются. Все говорят об одном, но пишут по-разному. Но именно это и держит в тонусе — приходится регулярно обновлять знания. Сожалею ли я о своем выборе? Нет. Всегда любил погружаться в математические задачи, а фронтенд затягивает. Можно сутки биться над багом, ненавидеть его, плеваться… А потом решить — и словить кайф. В такие моменты код полностью поглощает, заставляя забыть о сне и еде.
Стоит ли идти во фронтенд сейчас?
— Никогда не поздно. Да, путь у каждого свой, и рынок сейчас нестабилен. Но при глубоком погружении за год можно набрать нужные скиллы и попасть на коммерческий проект.
🔥 Открыт набор на новый марафон!
Сейчас в Clevertec проходит марафон для начинающих фронтенд‑разработчиков. Это возможность погрузиться в профессию, получить реальный опыт и, возможно, стать частью команды. Участие бесплатное. Успей зарегистрироваться!
После выхода Firefox 136 оказалось, что разработчики значительно испортили переработали стартовую страницу (about:newtab). В комментарии к новости о релизе я уже поделился своим решением, но по мере того, как подмечал новые детали, решил завести под это дело отдельный пост и время от времени допиливать его. Коротко о том, что мы исправляем: сетку с шорткатами сделали слишком узкой, слишком высокой, а при наведении курсора подпись «прыгает».
Прежде всего, для этой задачи не помогут аддоны типа Stylus, потому что по соображениям безопасности им запрещён доступ к стилизации внутренних страниц. Нам понадобится папка chrome в профиле FF. Под Windows это \AppData\Roaming\Mozilla\Firefox\Profiles\profile\chrome. Если вы хотите подправить что-то в интерфейсе (стилизовать тулбар, например), создайте там файл с именем userChrome.css. Например, так можно удалить недавно появившуюся кнопку для показа всех вкладок:
#alltabs-button { display: none !important; }
Но нам нужно поменять содержимое стартовой страницы, поэтому создадим в той же папке файл userContent.css.
Сетка стала узкой и высокой, потому что кто-то из дизайнеров поменял местами промежуток по горизонтали (20px → 0) и вертикали (0 → 20px). Будем надеяться, что хоть сознательно.
Вернём всё как было (ну, или можете установить свои значения):
ul.top-sites-list { column-gap: 20px !important; row-gap: 0 !important; }
Длинные заголовки при наведении мыши прыгают потому, что включается (при наведении, да!) режим переноса по словам. Пожалуйста, никогда так не делайте в пользовательских интерфейсах. Я не страдаю эпилепсией, но даже меня затошнило. Что уж говорить о более сенситивных личностях.
Ну и, наконец, шорткат можно сделать чуть побольше. Размеры его элементов рассчитываются на основе переменной, которая имеет значение 32px. Если добавить 4 пикселя, шорткат будет выглядеть, КМК, поприятнее:
:root { --size-item-large: 36px !important; }
P.S. Пользуясь случаем, хочу попросить рекомендаций: чем вы пользуетесь в качестве главной страницы? Чтобы там были шорткаты (с полноценными preview, которые зачем-то убрала Мозилла), погода, калькулятор и что-нибудь ещё? Думаю, не запилить ли свой аддон со всем этим блэкджеком.
Вот и подошёл к концу первый хакатон по $mol, где нужно было переписать не хитрое научное оупенсорс приложение (Github, Online) на самый инновационный веб-фреймворк. Так что встречайте финалистов:
🥁🥁🥁 🥁🥁🥁
₽150K получает PavelZubkov(PR, Online). Он сделал не только наиболее полное и качественное решение, но и не большой PR в $mol.
₽75K получает reatailret (PR, Online). Он прислал достойное оригинальное решение в виде PWA приложения, но оно всё же не дотягивает до лидера по многим факторам: от неработающей авторизации, до расположения файлов не по фен-шую.
₽50K получает Lyumih(PR, Online). Его решение было самым ранним, но, как ни печально, так и осталось недоработанным. Даже не смотря на часть кода взятую у PavelZubkov.
✨✨✨ ✨✨✨
Решение dukinm (PR) существенно основано на некорректно расположенных файлах от PavelZubkov, а правки носят в основном косметический характер. Однако, он единственный, кто написал хоть немного тестов и комментариев!
Запускаем бесплатный онлайн-марафон по фронтенд-разработке. Будет как в «Рокки»
Спринты, дедлайны и финальный тест-бой. Кто пройдет с нами три месяца подготовки — получит шанс на титул. Без метафор — мы реально ищем таланты и готовы взять их на стажировку.
Как записаться?
Заполни анкету по ссылке в профиле и скинь другу. Заявки принимаем до 26 марта.
Что будет?
Интенсивный 3-месячный тренинг. Это бесплатно. По сути, ты будешь поэтапно с дедлайнами писать приложение. Каждый спринт проверяем с помощью автотестов. Плюс будет поддержка менторов, наших крепких разработчиков. Это реальная прокачка твоих навыков и готовый проект в резюме.
Это уже четвертый марафон — после каждого наша команда фронтенд-разработчиков растет.
Кого ждём?
Начинающих веб-разработчиков (JS, React), которые уже изучали теорию и хотят прокачаться на практике в условиях, максимально близких к реальному проекту. Главное — желание кодить. Подойдут:
- студенты профильных вузов
- выпускники курсов
- самоучки
Важное условие: приглашаем участников из Беларуси и России.
Что дальше?
После 26 марта отправим на почту инструкции и первые задания. Старт марафона 1 апреля (это не шутка). До связи, Рокки.
Как мы сокращали количество запросов по фичам в API
Контекст: я отвечаю за разработку конструктора Telegram-приложений. Начинались мы как конструктор кликеров (еще до хомяка). Со временем эволюционировали в конструктор курсов, сообществ, визиток, мероприятий и любых других приложений
Одна из основных сущностей в коде — это BotUser. То есть пользователь, который появился в приложении (зашёл хотя бы раз), имеет имя и Telegram ID
За ~полгода проекта у нас добавилось много фич, привязанных к пользователю. Практически все сопоставляются 1 к 1 по ключу User ID. Например, квизы, бонусные дни, купленные страницы, купленный карточки апгрейдов, тариф и т.д.
Раньше для каждой новой фичи мы добавляли новый запрос в API с фронтенда. И вот мы заметили, что на каждый заход пользователя стало уходить >10 запросов в API ⚠️.
Примерно вот так:
GET /users/user
// Response
{
"tgUsername": ...,
"tgId": ...,
...
}
GET /users/features/quizzes/completed
// Response
{
"completedQuizzes": ...,
}
GET /users/features/pages/bought
// Response
{
"boughtPages": ...,
}
GET /users/features/rates/rate
// Response
{
"userRate": ...,
}
При этом, на каждый запрос мы проверяли авторизацию. В Telegram это делается с помощью хеша от Telegram + проверка подписи токеном бота
Следовательно, на каждый запрос мы делали JOIN пользователя, брали бота (сущность Bot) из кэша и мэтчили подпись (+ логгировали). Это лишняя нагрузка
Сейчас подсобрали все фичи в один запрос. Теперь, на каждый заход пользователя получается только один GET /app/account/data, который возвращает данные пользователя вместе с данными фичей:
не подгружаем связанные сущности, где не нужно (one-to-one, one-to-many);
если подгружаем сущности, всегда делаем это одним JOIN'ом (а не бегаем по 2-3 раза в БД, как любит делать Hibernate);
берём общие часто запрашиваемые данные из кэшей.
Это позволило снизить нагрузку на сервер и БД. К посту прикрепляю график загрузки части наших серверов по CPU до и после оптимизации.
---
Если вам понравился пост или оказался полезным, поставьте, пожалуйста лайк ❤️. Это мотивирует делиться опытом из разработки. И, как полагается, у меня есть Telegram-канал, в котором я рассказываю про разработку, развитие SaaS-сервисов и управление IT проектами.
В Joomla 4 и Joomla 5 появилась концепция Web Assets и WebAssetManager, с помощью которого можно управлять подключениями css, js файлов, подключением. Все css и js файлы включаются в общий реестр ассетов, затем выстраивается граф зависимостей и в итоге на генерируемую страницу подключается только то что нужно на данной странице.
Поскольку веб-ассеты можно добавлять с помощью плагинов (ссылка на статью ниже) - можно сказать, что появилось новое направление для плагинов - веб-ассеты. Вы можете устанавливать плагины, включающие веб-ассеты и использовать их как зависимости в самых разных местах Joomla: в шаблоне, в макетах модулей и плагинов.
Одним из таких плагинов веб-ассетов является WT JSwiper.js. Плагин добавляет в Joomla Web Assets Registry ассет популярного скрипта swiper.js, который потом легко можно использовать в коде:
use Joomla\CMS\Factory;
$wa = Factory::getApplication()->getDocument()->getWebAssetManager();
// Локальный файл
$wa->useScript('swiper-bundle')->useStyle('swiper-bundle');
// Подключение из CDN
$wa->usePreset('swiper-bundle-remote');
😐 Например, было: иконочный шрифт могут использовать 2 разных модуля. CSS обычно подключается в шаблоне и он грузится везде, даже там, где не надо. Если же подключать CSS в одном модуле, а в другом нет - на странице стиль есть ровно до тех пор, пока опубликован модуль с этим подключением.
👍 Стало: теперь в макетах расширений мы просто пишем $wa->useStyle('my.style'); и за необходимостью подключения нужного ассета (в данном случае CSS с иконочным шрифтом) следит Web Asset Manager. Если мы снимем один модуль с публикации, то нужный ассет подключит другой модуль.
Поскольку плагин - расширение Joomla - его можно обновлять обычным для Joomla способом и всегда иметь самую свежую версию любимого js-скрипта или веб-ассета на всех своих сайтах и сайтах ваших клиентов.
В этой версии, кроме обновления собственно ассета до версии 11.2.5 к нему добавился пока что частичный перевод документации Swiper на русский язык.
Представлен проект Scroll Buddy — анимация на полосе прокрутки.
«Вместо скучной полосы прокрутки я подумал, что было бы забавно иметь анимированную фигурку, которая ходит вверх и вниз по краю страницы, когда вы прокручиваете. Это первый прототип, который я сделал. Собираюсь сделать скейтбордиста, скалолаза или белку следующим», — пояснил авто проекта.
Я не делаю прогнозы по датам выхода, но хочу порассуждать на тему того, чего ожидаю от стабильной версии. И чего — точно нет.
Начну с последнего — каких изменений я не ожидаю
Изменение состава и сигнатур текущих методов. Если следить за выходом новых версий пакета Microsoft.Extensions.Caching.Hybrid, можно заметить, что методы объекта HybridCache не меняются уже давно. Из этого можно сделать вывод, что в стабильной версии мы увидим тоже самое, что наблюдаем сейчас.
Какие изменения я ожидаю увидеть
Удаление объекта из кэша по тегам. На момент написания статьи метод RemoveByTagAsync вообще не имел реализации. Сейчас в версии 9.2.0-preview.1.25105.6 он реализован и вполне себе работает, так что в релизную версию явно войдёт.
Не удивлюсь, если изменится логика присваивания тегов. Сейчас для многих она может быть неочевидной. Разберём пример:
Представим, что метод GetOrCreateAsync вызывается несколько раз с одним и тем же ключом, но разным набором тегов. Теги будут присвоены только при первом попадании объекта в кэш, то есть в момент его извлечения из хранилища. Когда проектируем приложение, не всегда заранее известно, в какой из вызовов GetOrCreateAsync объект будет извлекаться из кэша, а в какой — из хранилища. Оно и логично — метод специально создали так, чтобы мы не задумывались об этом. Соответственно, сейчас при вызове этого метода мы не можем определить, какой из наборов тегов ляжет в кэш.
И тут у меня два варианта развития событий: или логика поменяется и теги будут перезаписываться всегда — независимо от того, берётся объект из кэша или хранилища. Или при написании программы нужно будет следить, не передаём ли мы разные наборы тегов.
Наш давний друг Женя Блохин, учёный-химик из Питера, попросил нас помочь с простым мобильным оупенсорс клиентом для научной БД. Он сделал ставку на фреймворк $mol, чтобы поддержать отечественные технологии и показать их научному сообществу во всём мире.
Чтобы добиться самого высокого качества, мы проводим онлайн хакатон с призовым фондом в ₽300K, который будет справедливо поделён между всеми участниками. Задача очень простая: нужно переписать не хитрое научное оупенсорс приложение с VanillaJS на $mol - TypeScript фреймворк мирового уровня.
Подробности будут на этом канале23 февраля, когда хакатон начнётся. У вас будет неделя до 2 марта, чтобы неспеша вылизать своё решение. А ещё через неделю мы распределим места и объявим победителя, чей форк будет влит обратно в основной репозиторий. Да, у нас всё будет в открытую на платформе GitHub, чтобы каждый мог убедиться в справедливости судейства.
Участвуйте сами и призывайте в наши ряды новобранцев. Ещё не поздно до начала успеть освоить самый продвинутый фреймворк хотя бы на базовом уровне - этого уже будет достаточно, чтобы иметь шанс что-то выиграть.
Разница между масштабирование и зумом в CSS. Зум работает так же, как и масштабное преобразование, но в отличие от масштабирования, он влияет на макет страницы. Другими словами, макет страницы пересчитывается с учётом нового размера масштабируемого элемента.
Некоторых разработчиков и вебмастеров интересует останется ли плагин обратной совместимости в Joomla 6. Этот плагин был создан для того, чтобы сделать переход от версии к версии более гладким и бесшовным. Подробнее почитать о роли плагина можно в официальной документации на manual.joomla.org: Compatibility Plugin.
Устаревший код МОЖЕТ быть перемещен в плагин совместимости. Плагин обеспечивает более плавное обновление между основными версиями. Он содержит код из предыдущей версии, который может сломать сайт после обновления, поскольку расширение использует устаревший код. Расширение полностью совместимо только тогда, когда оно работает без проблем с отключенным плагином совместимости.
От версии к версии часть кода ядра Joomla помечается как устаревшая, а затем, спустя некоторое время удаляется из основного ядра и МОЖЕТ быть перемещена в плагин обратной совместимости. Эта концепция появилась при переходе от Joomla 4 к Joomla 5.
Важным уточнением является то, что для новой мажорной версии (joomla 3, joomla 4, joomla 5 и т.д.) плагин содержит устаревший код предыдущей версии. То есть для Joomla 5 это код из Joomla 4. Для Joomla 6 - код из Joomla 5.
Таким образом расширения, использующие методы и функции ядра Joomla и всё ещё работающие даже с плагином обратной совместимости на Joomla 5 в Joomla 6 скорее всего работать уже не будут. В Joomla 6 из плагина обратной совместимости будет удален код, поддерживающий обратную совместимость с Joomla 4. Таким образом стабильно работать в Joomla 6 будет то, что сейчас стабильно работает на Joomla 5 с отключённым плагином обратной совместимости.
Joomla-разработчикам: обращение к методам модели в HtmlView напрямую
Когда-то, давным-давно в одной далёкой галактике кто-то решил, что было бы неплохой идеей ввести в Joomla косвенный доступ к методам модели (MVC) для получения данных, добавив метод AbstractView::get(). Этот метод извлекает модель и затем запускает get(). Простыми словами, когда мы во View (файл HtmlView нашего компонента) видим конструкцию $this->item = $this->get('Item') это означает обращение к методу getItem() модели для текущего View.
Но такой подход исключает любую возможность подсказки типов, аргументов и т. д. и делает все излишне сложным. Поэтому разработчики ядра Joomla объявили этот метод устаревшим с этим PR 44162.
Новый способ выглядит так:
// Файл HtmlView компонента
public function display($tpl = null)
{
$model = $this->getModel();
$this->items = $model->getItems();
parent::display($tpl);
}
Старый подход (то есть метод get() во View) будет удалён в Joomla 7. Памятуя о релизном цикле Joomla, это означает, что:
осенью 2025г выйдет Joomla 6.
2 года она будет основной веткой. Joomla 5 будет в режиме поддержки
через 2 года, в 2027 выйдет Joomla 7, в которой будет удалён этот метод.
но Joomla 6 будет ещё 2 года в режиме тех.поддержки и в ней (до 2029 года) этот метод останется.
Таким образом у разработчиков есть от 2,5 до 4,5 лет (на момент написания этого поста) на то, чтобы сделать этот рефакторинг.