Модули, Clean Architecture и DI
Граница ответственности важнее числа слоёв
Отделите направление вызова от зависимости исходников
В Clean Architecture внутреннее правило не должно знать детали внешнего хранилища. Оно объявляет нужный контракт, внешняя реализация его выполняет, а точка сборки соединяет объекты. Вызов идёт к реализации во время выполнения, но зависимость исходников направлена к контракту. Robert C. Martin: Clean Architecture.
DI без обязательного контейнера
interface Notes { fun title(id: Long): String }
class Header(private val notes: Notes) {
fun text(id: Long): String = notes.title(id)
}
Передача Notes в конструктор — уже dependency injection. Dagger/Hilt/Koin автоматизируют сборку, но не выбирают удачные границы за разработчика. Вызов глобального locator скрывает зависимость от конструктора. Dependency injection.
Фича, API и реализация
Выделяйте модули вокруг связной функции или данных, минимизируйте публичный API. App может служить точкой сборки. Разбиение каждой сущности на отдельный модуль увеличит стоимость навигации и настройки без обязательной пользы. Границы модулей.
implementation скрывает зависимость от compile classpath потребителя; api экспортирует её. Если публичная сигнатура возвращает тип сторонней библиотеки, её уже нельзя честно считать скрытой деталью. Это правило сборки, не механизм безопасности. Gradle: api и implementation.
SOLID как проверяемые вопросы
SRP: какие разные причины меняют модуль? LSP: сохраняет ли замена реализации договор, включая ошибки и предусловия? ISP: вынуждены ли клиенты знать ненужные операции? DIP: знает ли правило конкретный SDK? OCP: можно ли добавить ожидаемый вариант поведения через выбранную точку расширения? Эти вопросы полезнее механического «интерфейс на каждый класс».
Для LSP первичная формулировка требует сохранения свойств, доказанных для базового типа, при подстановке подтипа: Liskov, Wing — A Behavioral Notion of Subtyping. Это договор наблюдаемого поведения, а не только совпадение сигнатур.
Android guidance допускает необязательный domain-слой; его схему зависимостей не следует выдавать за единственную каноническую схему Clean Architecture. Domain layer.
Основа отбора: draft/Architecture interview.md, draft/patterns.md, draft/faq500.md.