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

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

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

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

Обзор

Зависимости — это типы и функции в вашем приложении, которым нужно взаимодействовать с внешними системами, которые вы не контролируете. Классическими примерами этого являются API-клиенты, делающие сетевые запросы к серверам; но и безвредные на вид вещи, такие как инициализаторы UUID и Date, доступ к файлам, пользовательские настройки по умолчанию, и даже часы и таймеры - все это можно рассматривать как зависимости.

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

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

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

  • Зависимости, которые взаимодействуют со сторонними библиотеками, не принадлежащими Apple (например, Firebase, библиотеки веб-сокетов, сетевые библиотеками, библиотеками потокового видео и т. д.), как правило, много весят и дольше компилируются. Что способно замедлить цикл вашей разработки.

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

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

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

  • Как вы переопределите зависимости только для одной части вашего приложения? Это может быть сподручно(*удобно) - переопределять зависимости в тестах и в превью SwiftUI, а также в процессах, относящихся к пользователям, таких как введение в продукт.

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

Эта библиотека решает все вышеперечисленные вопросы и многое, многое другое.

Применение вашей первой зависимости

Библиотека позволяет вам регистрировать ваши собственные зависимости, но она также предоставляет множество управляемых зависимостей прямо “из коробки" (полный список см. в DependencyValues), и есть большая вероятность, что вы сразу же сможете применить одну из них. Если вы используете планировщики Date(), UUID(), Task.sleep или Combine непосредственно в логике вашей функции, то вы уже можете начать использовать эту библиотеку.

Любое место, где вы используете одну из этих зависимостей непосредственно в логике функции, не передавая её в функцию явно, может быть обновлено с помощью обертки свойств @Dependency, чтобы сначала объявить вашу зависимость в функции:

final class FeatureModel: ObservableObject {
  @Dependency(\.continuousClock) var clock  // Controllable async sleep
  @Dependency(\.date.now) var now           // Controllable current date
  @Dependency(\.mainQueue) var mainQueue    // Controllable main queue scheduling
  @Dependency(\.uuid) var uuid              // Controllable UUID creation

  // ...
}

Как только ваши зависимости объявлены, вместо того, чтобы напрямую обращаться к Date(), UUID(), Task и т. д., вы можете использовать зависимость, определенную в модели вашей функции:

final class FeatureModel: ObservableObject {
  // ...

  func addButtonTapped() async throws {
    try await self.clock.sleep(for: .seconds(1))  // 						
Источник: https://habr.com/ru/post/711208/


Интересные статьи

Интересные статьи

Привет! Меня зовут Женя, я UX-дизайнер в компании ISPsystem, создаю UI/UX-платформы BILLmanager. Работаю в этом направлении 4 года, а начинала свой путь с game-ux в Starfall Online. Затем сменила напр...
Для тех, кто не хочет слишком погружаться в юнит-экономику, и при этом ставить адекватные задачи маркетологу. Считаем окупаемость с показателями постоянных и переменных расходов, среднего чека и повто...
Сегодня, в предпоследний день уходящего года, хочу рассказать о созданном мной сервисе, помогающем быстро проектировать, отлаживать и следить за работоспособностью ботов ...
После публикации статьи прошло уже более двух лет, модели 1400 серии на сегодняшний день убраны из продажи. Пришло время для изменений и новшеств, эту задачу CheckPoint постара...
Как известно, управление ключами является одной из самых сложных задач в криптографии. Буквально на днях в качестве RFC 8645 опубликован документ “Re-keying Mechanisms for Symmetric Keys” («Мех...