What do you think about an idea to remove access to Context object in presenters to make it platform-independent? It could be achieved by making, for example, Navigator not Singleton but with PerView scope and add Host activity as a construtor parameter? Is it worth the sweat?
@romansbobans I think, the presenter should't have any platform dependencies, only java and then you can test presenter using only JUnit.
For navigation good solution is to use Router pattern. Like a View interface you have Router interface which define navigation methods.
For example:
public interface IRouter {
}
public interface CategoryRouter extends IRouter {
void openEditCategoryScreen(CategoryViewModel category);
}
public interface Router<R extends IRouter> {
void detachRouter();
void attachRouter(R router);
boolean hasRouter();
R getRouter();
}
md5-08df37e04c15aa064ca4b6c00ea72264
public abstract class BaseRouterPresenter<V extends MvpView, R extends IRouter>
extends BasePresenter<V> implements Router<R> {
private PresenterRouterDelegate<R> routerDelegate;
public BaseRouterPresenter() {
super();
routerDelegate = new PresenterRouterDelegate<>();
}
@Override public void detachRouter() {
routerDelegate.detachRouter();
}
@Override public void attachRouter(R router) {
routerDelegate.attachRouter(router);
}
@Override public boolean hasRouter() {
return routerDelegate.hasRouter();
}
@Override public R getRouter() {
return routerDelegate.getRouter();
}
}
````
md5-9036f6ae632dfbd33fc5aab77a899bb6
In you presenter
md5-bffcfb9187323f64442930671705847a
public class CategoriesActivity extends Activity implements CategoryRouter {
@Inject protected Navigator navigator;
@Override public void openEditCategoryScreen(CategoryViewModel category) {
navigator.navigateToAddCategoryScreen(this, category);
}
```
Why this pattern is good?
1) You code become more readable. Imagine the situation when you open Activity or Fragment and you want to understand navigation flow on this screen. For this you need to find code responsible for navigation. It will take some time, especially when you new on project.
With router you just need to open interface and see where you can go from this screen.
2) I think it's bad way to use Navigator in presenter, because Navigator containe all navigation logic.
And it's allow us to invoke any navigation method in presenter. It's bad, we need borders and router provide them.
3) Easy to test, just mock interface.
Sorry for my bad english :))
i totally agree! for that reason my presenters, models and view interfaces are in a separated java module.
Most helpful comment
@romansbobans I think, the presenter should't have any platform dependencies, only java and then you can test presenter using only JUnit.
For navigation good solution is to use Router pattern. Like a View interface you have Router interface which define navigation methods.
For example:
public class CategoriesActivity extends Activity implements CategoryRouter {
@Inject protected Navigator navigator;
@Override public void openEditCategoryScreen(CategoryViewModel category) {
navigator.navigateToAddCategoryScreen(this, category);
}
```
Why this pattern is good?
1) You code become more readable. Imagine the situation when you open Activity or Fragment and you want to understand navigation flow on this screen. For this you need to find code responsible for navigation. It will take some time, especially when you new on project.
With router you just need to open interface and see where you can go from this screen.
2) I think it's bad way to use Navigator in presenter, because Navigator containe all navigation logic.
And it's allow us to invoke any navigation method in presenter. It's bad, we need borders and router provide them.
3) Easy to test, just mock interface.
Sorry for my bad english :))