如何以 MVP 模式将上下文传递给存储库

How to pass context to repository in MVP pattern

我一直在学习和整合MVP pattern,问题很少。

我从这张图中了解到的是

Activity 将创建 Presenter 的实例,并将其引用和 model 对象传递给演示者

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

接下来如果演示者需要从本地偏好或远程存储或获取任何数据,它将询问模型。

然后模型将请求存储库存储和检索数据。

我遵循了一些教程,这就是我实现该模式的方式。

界面

public interface MainActivityMVP {

    public interface Model{

    }

    public interface View{
        boolean isPnTokenRegistered();
    }

    public interface Presenter{

    }
}

Activity

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

主持人

public void sendDataToServer() {

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

现在的问题是我需要上下文才能访问 sharedPreference,但我没有在任何地方传递 context。我也不想使用 static context。我想知道将上下文传递给 MVP 模式的正确方法。

嗯,最好的方法是将您的首选项 class 包装在帮助程序 class 中,然后使用 Dagger 将其注入到您需要的任何地方,这样您的 presenter/model不需要知道上下文。 例如,我有一个提供各种单例的应用程序模块,其中之一是我的 Preferences Util class,它处理共享首选项。

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

现在,只要我想使用它,只需@Inject 即可:

@Inject
PreferencesUtil prefs;

我认为学习曲线是值得的,因为您的 MVP 项目将更加解耦。

但是,如果您愿意忘记 "Presenter doesn't know about Android context" 规则,您只需将 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。

您也可以按照评论中的建议使用 application conext。

您还没有找到想要的东西。你有一个模型接口,所以你有一个实现这个接口的class,可能是这样的:

MainModel implements MainActivityMVP.Model{
    SharedPreferences mPrefs;

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

因此,您只需将该引用传递给演示者,而不是接收 MainModel class,您可以接收 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 方法添加到您的 presenter/view/model 接口中。你应该有这样的东西:

public interface MainActivityMVP {

    public interface Model{
        void saveOnSharedPreferences();
    }

    public interface View{
        boolean isPnTokenRegistered();
    }

    public interface Presenter{
        void sendDataToServer();
    }
}