Answer the question
In order to leave comments, you need to log in
Android, MVP. How to determine whether to include a method in an interface or not?
Hello.
There is a popular short example of the implementation of the mvp pattern in android using the login page as an example. I'll simplify it and get to the point:
The view interface contains a method that will direct us to the user's page if the login is successful:
public interface LoginView {
void navigateToHome();
}
public interface LoginPresenter {
void login();
}
Answer the question
In order to leave comments, you need to log in
IMHO, this is a terrible mess.
View must have methods for displaying data only. navigateToHome is not one of them, it should be a separate Router object, which is not in the MVP.
View should not have a link to Presenter and pull some methods from it.
There should be no business logic in the View.
The Presenter must have a reference to the View.
Events (rx observable or callbacks, for example) that the Presenter subscribes to should stick out from the View.
The Presenter must have two methods to bind it to the View: bind(View), unbind(View).
Fragment or Activity must not be a View, Presenter or Model. They are the glue, the system mechanisms for linking and maintaining the stack of screens. They somehow create or receive instances of View and Presenter through DI, and bind them using bind / unbind.
Thus, there will be no validate methods in any interface, and in any implementation (unless they are private implementation methods, of course).
Simplified like this
interface LoginView {
@NonNull Observable<String> names();
@NonNull Observable<String> passwords();
void showError(@NonNull String error);
}
interface LoginPresenter {
void bind(@NonNull LoginView view);
void unbind(@NonNull LoginView view);
}
interface Router {
void navigateToHome();
}
class LoginPresenterImpl implements LoginPresenter {
@Inject
LoginPresenterImpl(router: Router){...}
private CompositeDisposable disposables = new CompositeDisposable();
@Override
void bind(@NonNull LoginView view) {
disposable.add(
Observable.combineLatest(view.names(), view.passwords(), (name, password) -> validate(name, password))
.doOnNext(validated -> {if(!validated) view.showError("invalid login")}
.filter(it -> it)
.subscribe(it -> router.navigateToHome())
);
}
@Override
void unbind(@NonNull LoginView view) {
disposables.clear();
}
}
class Fragment {
@Injecte
LoginPresenter presenter;
@Inject
LoginView view;
onViewCreated() {
presenter.bind(view)
}
onDestroyView() {
presenter.unbind(view);
}
}
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question