Search code examples
androidperformanceandroid-layoutandroid-mvp

Is it fine to create a separate interface for call back function in MVP pattern


I am trying to create an app by using MVP design pattern. This is the first time i am using this pattern, thats the reason i am little concerned that either i am following the pattern correctly or not.

This is what i have done so far. I am not using Dagger2.

Interface

public interface MainActivityMVP {

    interface Model{
        void sendTokenToServer(MainActivityMVP.Presenter presenter);
    }

    interface View{
        boolean isPnTokenRegistered();
        void tokenUpdated();
        void tokenFailedToUpdate();
    }

    interface Presenter{
        void tokenUpdatedSuccessfully();
        void tokenAlreadyExists();
        void detachView();
    }

On MainActivity, I have created an instance of Presenter and Model and pass the Model object to Presenter Constructor

MainActivity

    public class MainActivity extends BaseActivity implements MainActivityMVP.View {

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_base);

            mainPresenter= new MainPresenter(this, new MainModel());
            mainPresenter.sendFCMTokenToServer();
        }

On Presenter I call Model's method to perform operation, and pass presenter reference to it.

Presenter

    public class MainPresenter implements MainActivityMVP.Presenter{

        MainActivityMVP.View view;
        MainActivityMVP.Model model;


        public MainPresenter(MainActivityMVP.View view, MainActivityMVP.Model model){
            this.view= view;
            this.model= model;
        }


        public void sendFCMTokenToServer() {
            model.sendTokenToServer(this);
        }

       @Override
       public void tokenUpdatedSuccessfully() {
         view.tokenUpdated();
       }

        @Override
        public void tokenAlreadyExists() {
          view.tokenFailedToUpdate();
        }

In Model, I create instance of PreferenceManager class that gets data from SharedPreference

public class MainModel implements MainActivityMVP.Model {

    PreferencesHelper preferencesHelper;


    public MainModel(){
        preferencesHelper= new PreferencesHelper();
    }

 @Override
    public void sendTokenToServer(MainActivityMVP.Presenter presenter) {

        if (preferencesHelper.getNotificationSettings().isEmpty()) {
           //do stuff

           presenter.tokenUpdatedSuccessfully();
        }
  }

Now i have these questions.

  • Is the above approach of implementing MVP pattern is fine, or i am missing something here.

  • Is it fine if i add an other interface for call backs, or passing Presenter to model is better approach, as i have seen some example where they pass interactor reference to model.

  • Is it necessary to create Interactor Class in MVP pattern

  • Is it fine, and not against MVP rule if i create a separate interface for Repository,


Solution

  • Developers have different varieties of implementing MVP. Few people use interactors. Its is not compulsory to use interactors in MVP. I will suggest you below since you are in a starting stage.

     public interface MainView extends BaseView {
             boolean isPnTokenRegistered();
             void tokenUpdated();
             void tokenFailedToUpdate(); 
    }
    

    Then have your basepresenter be like this

    public interface BasePresenter<V extends BaseView> {
    
        void setView(V view);
    
        void destroyView();
    
        void destroy();
    }
    

    Now your MainPresenter

        public class MainPresenter implements BasePresenter<MainView>{
    
        MainView view;
        PreferencesHelper preferencesHelper;
    
       MainPresenter(){
            preferencesHelper= new PreferencesHelper();
       }
    
          @Override
          public void setView(MainView view) {
            this.view = view;
          }
    
          @Override
          public void destroyView() {
            this.view = null;
          }
    
          @Override
          public void destroy() {
    
          }
    
           public void sendFCMTokenToServer() {
                //Do whatever you want
            }
    
        }
    

    Finally have your activity like this,

    public class MainActivity extends BaseActivity implements MainView {
    
            MainPresenter mainPresenter;
    
            @Override
            protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.activity_base);
                mainPresenter= new MainPresenter();
                mainPresenter.attachView(this)
                mainPresenter.sendFCMTokenToServer();
    
            }