我正在尝试在没有 Dagger 的情况下实现 MVP(出于学习目的).但我遇到了问题 - 我使用存储库模式从缓存(共享首选项)或网络获取原始数据:
I'm trying to implement MVP without Dagger (for learning purposes). But I got to the problem - I use Repository patter to get raw data either from cache (Shared Preferences) or network:
Shared Prefs|
|<->Repository<->Model<->Presenter<->View
Network|
但是为了让我的手放在共享首选项上,我必须放在某个地方,比如
But to put my hands on Shared Preferences I have to put somewhere line like
presenter = new Presenter(getApplicationContext());
我使用 onRetainCustomNonConfigurationInstance
/getLastCustomNonConfigurationInstance
对来保持 Presenter 保留".
I use onRetainCustomNonConfigurationInstance
/getLastCustomNonConfigurationInstance
pair to keep Presenter "retained".
public class MyActivity extends AppCompatActivity implements MvpView {
@Override
protected void onCreate(Bundle savedInstanceState) {
//...
presenter = (MvpPresenter) getLastCustomNonConfigurationInstance();
if(null == presenter){
presenter = new Presenter(getApplicationContext());
}
presenter.attachView(this);
}
@Override
public Object onRetainCustomNonConfigurationInstance() {
return presenter;
}
//...
}
那么如何在没有 Dagger 的情况下在 MVP 中使用 Shared Preferences 并且不会导致 Presenter 依赖于上下文?
你的 Presenter 不应该首先依赖于 Context
.如果您的演示者需要 SharedPreferences
,您应该将它们传入 构造函数.
如果您的演示者需要 Repository
,再次将其放入 constructor.我强烈建议观看 Google 清洁代码讲座,因为他们在解释方面做得非常好为什么你应该使用合适的 API.
Your Presenter should not be Context
dependent in the first place. If your presenter needs SharedPreferences
you should pass them in the constructor.
If your presenter needs a Repository
, again, put that in the constructor. I highly suggest watching Google clean code talks since they do a really good job explaining why you should use a proper API.
这是正确的依赖管理,它将帮助您编写干净、可维护和可测试的代码.并且无论您使用匕首、其他 DI 工具还是自己提供对象都无关紧要.
This is proper dependency management, which will help you write clean, maintainable, and testable code. And whether you use dagger, some other DI tool, or supply the objects yourself is irrelevant.
public class MyActivity extends AppCompatActivity implements MvpView {
@Override
protected void onCreate(Bundle savedInstanceState) {
SharedPreferences preferences = // get your preferences
ApiClient apiClient = // get your network handling object
Repository repository = new Repository(apiClient, preferences);
presenter = new Presenter(repository);
}
}
可以通过使用工厂模式或一些 DI 框架(如 dagger)来简化此对象创建,但正如您在上面看到的那样,Repository
和您的 Presenter 都不依赖于 Context
.如果您想提供实际的 SharedPreferences
,则只有它们的 创建 将取决于上下文.
This object creation can be simplified by using a factory pattern, or some DI framework like dagger, but as you can see above neither Repository
nor your presenter depends on a Context
. If you want to supply your actual SharedPreferences
only their creation of them will depend on the context.
您的存储库依赖于一些 API 客户端和 SharedPreferences
,您的演示者依赖于 Repository
.只需向它们提供模拟对象即可轻松测试这两个类.
Your repository depends on some API client and SharedPreferences
, your presenter depends on the Repository
. Both classes can easily be tested by just supplying mocked objects to them.
没有任何静态代码.没有任何副作用.
Without any static code. Without any side effects.
这篇关于如何在没有 Dagger 的情况下在 MVP 中使用共享首选项并且不会导致 Presenter 依赖于上下文?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!