|
22 | 22 |
|
23 | 23 | Итак, начнем с простого. Каждый экран должен быть независим. И каждый экран представляет собой классический архитектурный слоеный пирог. Например, экран принятия лицензии внешне будет выглядеть вот так:<br>
|
24 | 24 | 
|
| 25 | + |
25 | 26 | А архитектурно вот так:
|
| 27 | + |
26 | 28 | 
|
27 | 29 |
|
28 | 30 | И так для каждого экрана. <br>
|
@@ -94,7 +96,7 @@ public class LicensePresenter extends MvpPresenter<LicenseView> {
|
94 | 96 | Поэтому введем новую сущность под названием **SmartRouter**:<br>
|
95 | 97 | 
|
96 | 98 | **SmartRouter** ответственен за навигацию между экранами, содержит некоторую логику, на основании которой принимает решение о следующем шаге, и содержит некоторые состояния (обычно одно состояние - текущий шаг).<br>
|
97 |
| -Давайте посмотрим, как выглядит `WizardSmartRouter` вживую:<br> |
| 99 | +Давайте посмотрим, как выглядит `MainWizardSmartRouter` вживую:<br> |
98 | 100 | ```java
|
99 | 101 | public class MainWizardSmartRouter {
|
100 | 102 |
|
@@ -184,8 +186,8 @@ public class MainWizardSmartRouter {
|
184 | 186 | Вы можете заметить имплементации известных нам уже `InfoWizardPart`, `LicenseWizardPart` и `ActivationWizardPart`. `currentWizardStep` - это состояние текущего шага Визарда. Ну а вопросы непосредственной навигации делегируются через также известный нам `Router`. Если количество используемых в Визарде экранов большое, то имплементации интерфейсов можно вынести в отдельные классы.<br>
|
185 | 187 | Таким образом мы получаем единую сущность, ответственную за организацию Визарда, сущность, которая объединяет все, по сути, независимые экраны.<br>
|
186 | 188 |
|
187 |
| -Детали реализации вы можете посмотреть в [примере](https://github.com/AndroidArchitecture/WizardCase/tree/sample_1). Как там это все выглядит с Dagger2 и Moxy. Обязательно просмотрите код, прежде чем продолжать читать дальше.<br> |
188 |
| -Что еще хочу добавить к деталям реализации. Визард реализован по канонам Андроида, то есть одна Активити для всего Визарда (`MainActivity`) с тремя в данном случае фрагментами (`InfoFragment`, `LicenseFragment`, `ActivationFragment`). Поэтому в `MainActivity` реализован `NavigatorHolder` для роутинга, и также стартуется Визард (вызов `wizardSmartRouter.startWizard()` в `onResume()`).<br> |
| 189 | +Детали реализации вы можете посмотреть в [примере](https://github.com/AndroidArchitecture/WizardCase/tree/sample_1) и как там это все выглядит вместе с Dagger2 и Moxy. Обязательно просмотрите код, прежде чем продолжать читать дальше.<br> |
| 190 | +Что еще хочу добавить к деталям реализации: визард реализован по канонам Андроида, то есть одна Активити для всего Визарда (`MainActivity`) с тремя в данном случае фрагментами (`InfoFragment`, `LicenseFragment`, `ActivationFragment`). Поэтому в `MainActivity` реализован `NavigatorHolder` для роутинга, и также стартуется Визард (вызов `wizardSmartRouter.startWizard()` в `onResume()`).<br> |
189 | 191 | С точки зрения Даггера мы имеем два модуля (`WizardModule` и `WizardNavigationModule`), соединенных вместе в `WizardComponent`. Вообщем-то и все особенности.<br>
|
190 | 192 |
|
191 | 193 | Начнем усложнять нашу жизнь. Представим, что нам необходимо реализовать такой Визард:<br>
|
@@ -294,30 +296,36 @@ public class InfoFinishFragment extends InfoFragment {
|
294 | 296 | В итоге получаем максимально простую переиспользуемость одного и того же экрана в рамках одного Визарда. Более подробно код [здесь (ветка sample_2)](https://github.com/AndroidArchitecture/WizardCase/tree/sample_2).<br>
|
295 | 297 |
|
296 | 298 | А теперь представим такой пример:<br>
|
| 299 | + |
297 | 300 | 
|
| 301 | + |
298 | 302 | Активация немного усложнилась =) Рассмотрим поподробнее, что происходит. <br>
|
299 |
| -Допустим, мы на экране Активации сейчас (**Activation screen**):<br> |
| 303 | +Допустим, что сейчас мы на экране Активации (**Activation screen**):<br> |
| 304 | + |
300 | 305 | 
|
301 | 306 |
|
302 | 307 | По нажатию на кнопку "To personal account" пользователь попадает на экраны логина/регистрации.<br>
|
303 | 308 | Сначала нас ждет снова информационный экран (нижний в схеме **Information screen**):<br>
|
| 309 | + |
304 | 310 | 
|
305 | 311 |
|
306 | 312 | Далее экран Логина (**Login screen**):<br>
|
| 313 | + |
307 | 314 | 
|
308 | 315 |
|
309 |
| -На этом экране мы можем ввести свои креды и попасть на финальный экран Визарда. Либо же зарегистрировать новый аккаунт (**Registration screen**):<br> |
| 316 | +На этом экране мы можем ввести свои креды и попасть на финальный экран Визарда, либо же зарегистрировать новый аккаунт (**Registration screen**):<br> |
| 317 | + |
310 | 318 | 
|
311 | 319 |
|
312 | 320 | И если регистрация проходит успешно, то мы также попадем на финальный экран Визарда.<br>
|
313 |
| -А теперь еще такая вводная. У нас есть несколько визардов, и во всех них может понадобиться логин/регистрация. Получается, что во всех визардах нам придется вводить эти три экрана, логика взаимодействия которых между друг другом везде одинаковая. <br> |
| 321 | +А теперь еще такая вводная: у нас есть несколько визардов, и в любом из них может понадобиться логин/регистрация. Получается, что во всех визардах нам придется вводить эти три экрана, логика взаимодействия которых между друг другом везде одинаковая. <br> |
314 | 322 | Разве никак нельзя как-то избежать этого безжалостного дублирования кода? На самом деле можно. Давайте еще раз взглянем на схему:<br>
|
315 | 323 | 
|
316 | 324 |
|
317 | 325 | На самом деле ее можно трансформитровать до такой схемы:<br>
|
318 | 326 | 
|
319 | 327 |
|
320 |
| -То есть последовательность экранов InformationScreen, LoginScreen и RegistrationScreen и логику их взаимодействия мы выделяем в новый **AccountWizard**. И данный **AccountWizard** может сообщить внешнему Визарду, допустим, только две вещи:<br> |
| 328 | +То есть последовательность экранов InformationScreen, LoginScreen и RegistrationScreen и логику их взаимодействия мы выделяем в новый **AccountWizard**. Этот **AccountWizard** может сообщить внешнему Визарду, допустим, только две вещи:<br> |
321 | 329 | - пользователь вошел в нашу систему (залогинился или зарегистрировался, неважно),<br>
|
322 | 330 | - пользователь не вошел в нашу систему (будем полагать, что просто вышел с данных экранов, ошибки логина/регистрации вовне не выносим).<br>
|
323 | 331 |
|
@@ -419,7 +427,7 @@ public class AccountWizardSmartRouter {
|
419 | 427 | ```
|
420 | 428 |
|
421 | 429 | Особо ничего нового за исключением того, что в необходимых местах дергается ```AccountWizardPart```.<br>
|
422 |
| -Данный визард с технической точки зрения реализован точно также, как мы до этого реализовывали MainWizard. То есть это:<br> |
| 430 | +Данный визард с технической точки зрения реализован точно также, как мы до этого реализовывали ```MainWizardSmartRouter```. То есть это:<br> |
423 | 431 | - android: отдельная активити (```AccountActivity```) с тремя фрагментами (```InfoAccountFragment```, ```LicenseFragment```, ```RegistrationFragment```),<br>
|
424 | 432 | - dagger2: два модуля (```AccountWizardModule```, ```AccountNavigationModule```), замыкающихся в одном компоненте (```AccountWizardComponent```) со своим скоупом (```AccountWizardScope```). ```AccountWizardComponent``` является сабкомпонентом от ```WizardComponent```.<br>
|
425 | 433 |
|
@@ -548,5 +556,5 @@ public class MainWizardSmartRouter {
|
548 | 556 | }
|
549 | 557 | ```
|
550 | 558 |
|
551 |
| -По сути добавился еще один ```...wizardPart``` интерфейс и все. А то, что под этим ```AccountWizardPart``` скрывается отдельный Визард, MainWizard не знает. И в этом основная красота построения Визардов через **SmartRouter** и интерфейсы **...wizardPart**.<br> |
| 559 | +По сути добавился еще один ```...wizardPart``` интерфейс и все. А то, что под этим ```AccountWizardPart``` скрывается отдельный Визард, ```MainWizardSmartRouter``` не знает. И в этом основная красота построения Визардов через **SmartRouter** и интерфейсы **...wizardPart**.<br> |
552 | 560 | В итоге подобное построение Визардов позволяет достигнуть обозначенных выше целей.
|
0 commit comments