Intent-функции внутри View
-интерфейса должны называться исходя из "намерения" пользователя, их имена должны отвечать на вопрос "что именно хочет сделать пользователь?", и не должны в своём имени содержать какие-то детали имплементации внутри View
.
Распространённой ошибкой, являются, например, такие имена:
interface View {
fun continueButtonClickIntent(): Observable<Unit>
fun snackbarCloseIntent(): Observable<Unit>
}
В первом случае, continueButtonClicked
содержит сразу две ошибки: во-первых, упоминание Clicked
, являет собой пример того, что "наружу" просочились детали представления — а именно, что есть некий UI-элемент, который можно кликать. Однажды это может измениться, например, этот intent будет порождаться не кнопкой, а неким другим элементом UI, например checkbox-ом или ещё чем-то более экзотическим, или даже набором из нескольких элементов (их события могут быть объединены через Observable.merge()
). Во-вторых, ошибочно упоминаяется Button
, по аналогичным соображениям - это может не выдержать тест временем.
Во втором случае, практически те же ошибки - "светится" то, что имплементация содержит снэкбар, который умеет закрываться.
Чтобы прийти к правильному решению, нужно представить себя в роли пользователя и задать вопрос, "каково моё намерение, при совершении этих действий с интерфейсом"?
Ответы могут быть такими:
- Я нажимаю кнопку 'continue', чтобы выполнить логин. Хорошее имя для intent-а здесь тогда:
fun loginIntent()
- Я нажимаю кнопку 'continue', чтобы перейти к следующему шагу. Имя:
fun switchToNextStepIntent()
- Я нажимаю кнопку 'continue', чтобы продолжить - в самом общем смысле. Имя
fun continueIntent()
- Я нажимаю кнопку 'закрыть снэк бар', чтобы спрятать сообщение об ошибке логина:
fun hideLoginErrorMessageIntent()
Заметьте, что в примерах выше нигде не фигурируют ни специфические типы ui-элементов, ни специфичные для них события.
Такие имена способствуют тому, что View
-interface оказывается достаточно отвязан от деталей его представления в Android UI, и, кроме того, достаточно устойчив к любым косметическим и презентационным изменениям. Менять эти имена потребуется только при изменениях, касающихся какой-то презентационной логики.
Неправильно:
interface View {
fun messageClosedIntent(): Observable<Unit>
fun continueRequestedIntent(): Observable<Unit>
}
Правильно:
interface View {
fun closeMessageIntent(): Observable<Unit>
fun continueIntent(): Observable<Unit>
}