🔥

Тред (Миша Харитончик)


🧩 Модульная архитектура после первого десятка фреймворков неизбежно превратится в вертикальный граф зависимостей, это заблокирует возможность параллельной сборки, а также возникнет проблема невозможности взаимного импортирования фичемодулей (A.framework <-> B.framework).

Решение этих проблем кроется в создании банальной прокси для межмодульного взаимодействия Фичемодулей, теперь они не используют друг друга напрямую, а «общаются» через технический.framework Граф зависимостей становится плоским, гарантируется отсутствие циклических зависимостей

Неправильно: фичемодульА -> фичемодульБ Правильно: фичемодульА -> технический.framework •••> фичемодульБ Технический Фреймворк должен неявно (без импортирования) знать о том какие есть публичные интерфейсы и какой объект(принадлежащий более верхнеуровнему модулю) реализует его

У нас есть нечто особенное для разделения модулей по слоям, мы уходим от отдельного прокси фреймворка в сторону более гибкой схемы с разделением модуля на фреймворка «интерфейса» и «имплементации».

«Интерфейс» фреймворки не могут импортировать другие «интерфейс» фреймворки, «имплементации» свободно импортируют «интерфейсы» но не могут импортировать «имплементации» Модуль состоит из: Interface.framework Implementation.framework Mock.framework (фейк имплементация интерфейса)

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

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

На сегодняшний день улучшеная реализация легаси прокси имеет минимальный оверхед в рантайме, все что возможно предрассчитывается и подставляется кодгеном

Миша ХаритончикМиша Харитончик