Как передать контекст в хранилище в шаблоне MVP - PullRequest
0 голосов
/ 03 мая 2018

Я изучал и интегрировал MVP pattern, и у меня мало вопросов.

Что я понял из этой диаграммы, так это

Activity создаст экземпляр Presenter и передаст его ссылку и model объект докладчику

MainPresenter mainPresenter = new MainPresenter(this, new MainModel());

Далее, если докладчику необходимо сохранить или получить какие-либо данные из локальных предпочтений или удаленно, он запросит модель.

И тогда модель попросит хранилище для хранения и извлечения данных.

enter image description here

Я следовал нескольким учебникам, и вот как я реализую шаблон.

Интерфейс

public interface MainActivityMVP {

    public interface Model{

    }

    public interface View{
        boolean isPnTokenRegistered();
    }

    public interface Presenter{

    }
}

Активность

MainPresenter mainPresenter = new MainPresenter(this, new MainModel());
mainPresenter.sendDataToServer();

Presenter

public void sendDataToServer() {

    //  Here i need to ask `model` to check 
        do network operation and save data in preference
}

Теперь проблема в том, что мне нужен контекст для доступа к sharedPreference, но я нигде не прошел context. Я также не хочу использовать static context. Я хочу знать правильный способ передачи контекста в шаблон MVP.

Ответы [ 2 ]

0 голосов
/ 05 мая 2018

Вы не так далеко от того, что вы ищете. У вас есть интерфейс модели, поэтому у вас есть класс, который реализует этот интерфейс, возможно, что-то вроде этого:

MainModel implements MainActivityMVP.Model{
    SharedPreferences mPrefs;

    MainModel(Context context){
        mPrefs =context.getSharedPreferences("preferences",Context.MODE_PRIVATE);
    }
}

Таким образом, вам нужно только передать эту ссылку своему докладчику, но вместо того, чтобы получить класс MainModel, вместо этого вы можете получить MainActivityMVP.Model.

MainActivityMVP.Presenter mainPresenter = new MainPresenter(this, new MainModel(getContext()));

MainPresenter implements MainActivityMVP.Presenter{

     MainActivityMVP.View mView;
     MainActivityMVP.Model mModel;

     MainPresenter(MainActivityMVP.View view, MainActivityMVP.Model model){
           mView = view;
           mModel = model;
     }
}

Таким образом, у вас нет контекстной ссылки на вашего докладчика, а ссылка на вашу MainModel, а не на MainActivityMVP.Model.

Добавьте любой публичный метод в интерфейсы презентатора / вида / модели. У вас должно быть что-то вроде этого:

public interface MainActivityMVP {

    public interface Model{
        void saveOnSharedPreferences();
    }

    public interface View{
        boolean isPnTokenRegistered();
    }

    public interface Presenter{
        void sendDataToServer();
    }
}
0 голосов
/ 03 мая 2018

Что ж, лучший подход - это обернуть ваш класс предпочтений во вспомогательный класс и использовать Dagger , чтобы внедрить его туда, где вам нужно, чтобы ваш докладчик / модель не должен был знать о контексте. Например, у меня есть модуль приложения, который предоставляет различные синглтоны, одним из которых является мой класс Preferences Util, который имеет дело с общими настройками.

@Provides
@Singleton
public PreferencesUtil providesPreferences(Application application) {
    return new PreferencesUtil(application);
}

Теперь, когда я захочу его использовать, я просто @Inject:

@Inject
PreferencesUtil prefs;

Я думаю, что обучение стоит того, поскольку ваш проект MVP будет более отсоединенным.

Однако, если вы хотите забыть о правиле «Ведущий не знает о контексте Android», вы можете просто добавить метод getContext в интерфейс представления и получить контекст из представления:

public interface MainActivityMVP {

    public interface Model{

    }

    public interface View{
        boolean isPnTokenRegistered();
        Context getContext();
    }

    public interface Presenter{

    }
}

А потом:

public void sendDataToServer() {
      Context context = view.getContext();
}

Я видел, как некоторые люди используют MVP таким образом, но я лично предпочитаю использовать Dagger.

Вы также можете использовать приложение conext, как это предлагается в комментариях.

...