I'm trying to understand concept of MvP design pattern. I mean, I get it, its quite easy. The main problem is optimal implementation. I tried to make my own BaseActivity, BasePresenter and BaseView just to extract part of a joint from all of my activities, I've done this this way:
BaseActivity
public abstract class BaseActivity<T extends BasePresenter<? extends IBaseView>> extends FragmentActivity implements IBaseView {
protected T presenter;
private ActivityConfig activityConfig;
@Override
final protected void onCreate(Bundle savedInstanceState) {
activityConfig = getConfig();
super.onCreate(savedInstanceState);
presenter = createPresenter();
setContentView();
initLibraries();
prepareView(savedInstanceState);
addFragments();
}
protected abstract ActivityConfig getConfig();
protected abstract T createPresenter();
protected abstract void prepareView(Bundle savedInstanceState);
protected abstract void addFragments();
private void setContentView(){
View root = View.inflate(this, activityConfig.layoutId, null);
setContentView(root);
}
private void initLibraries() {
ButterKnife.bind(this);
Timber.plant(new Timber.DebugTree());
}
@Override
public BaseActivity getCurrentContext() {
return this;
}
@Override
public T getPresenter() {
return presenter;
}
}
BasePresenter
public abstract class BasePresenter<T extends IBaseView> {
public abstract void loadData(boolean refresh);
}
BaseView
public interface IBaseView {
BaseActivity getCurrentContext();
BasePresenter getPresenter();
}
It works fine but I feel like this is bad designed so I want to use Mosby instead. The problem is that all of the tutorials don't touch aspect of base classes, they just use Mosby's ones as base (with is bad I suppose? couse I have to duplicate my code (Butterknife.bind() for example). So can you guys give me some good designed quickstart classes for Mosby MVP or give me some tips how should I divide my project? Thanks!
So I see two possibilities:
You could extend from Mosby's MvpActivity
as your base class and add your staff like initView()
, initLibraries()
etc. So that BaseActivity<P extends BasePresenter<? extends BaseView>> extends MvpActivity<P> implements BaseView
. Then MyFooActivity extends BaseActivity<FooPresenter>
. So you include Butterknife once in BaseActivity
and it should work. However, you might have to duplicate that code like Butterknife.bind()` for Fragments, as Activity and Fragments obviously don't have the same super class. I will show you how to solve that above.
Do the other way around: Integrate Mosby's functionality into your BaseActivity
. Mosby is build with the principle of "favor composition over inheritance". So what does this actually mean? Mosby offers a ActivityMvpDelegate
. As the name already suggests this delegate does all the work of instantiating Presenter etc. But instead of inheriting from MvpActivity
you use this delegate and invoke the corresponding delegate methods. Actually Mosby's MvpActivity
is doing exactly that if you have a look at the source code. So instead of extending from Mosby'sMvpActivity
you simply use MvpActivityDelegate
in your BaseActivity
.
So what about duplicating code like Butterknife.bind()
i.e. in Activity and Fragment. Well, Mosby can share his code like instantiating Presenter etc. between Activity and Fragment because both use the mosby delegate.
So you could apply the same principle: You could put the shared code into a delegate and call the delegate from both, activity and fragments.
The question is: is it worth i.e. Butterknife.bind()
is just one single call. You would also have to make one single call yourDelegate.doSomething()
...
But if you have to reuse "critical code" between activity and fragments then favor composition like Mosby does.
If you know that you are only working with Activites
then extending from Mosby's MvpActivity would also be a good option as described in 1. solution.