MVP模型是否应该包含特定于android的术语?
我可以在MVP视图中做逻辑上的事情,但据我所知,根据MVP模式,视图应该尽可能地愚蠢。MVP模型可以包含android特定的术语吗?如果没有,那么我如何在MVP模型中使用活动上下文呢?让我们假设基于MVP模式的登录功能的实现,其中模型(LoginInteractor)将使用活动上下文 因此,我们必须实现以下类:MVP模型是否应该包含特定于android的术语?,android,android-context,android-mvp,Android,Android Context,Android Mvp,我可以在MVP视图中做逻辑上的事情,但据我所知,根据MVP模式,视图应该尽可能地愚蠢。MVP模型可以包含android特定的术语吗?如果没有,那么我如何在MVP模型中使用活动上下文呢?让我们假设基于MVP模式的登录功能的实现,其中模型(LoginInteractor)将使用活动上下文 因此,我们必须实现以下类:LoginActivity、LoginPresentImpl和LoginInteractorImpl(作为MVP模型)。正如MVP所说,我们将在视图和演示者之间定义一个契约。我们将它们命名
LoginActivity
、LoginPresentImpl
和LoginInteractorImpl
(作为MVP模型)。正如MVP所说,我们将在视图和演示者之间定义一个契约。我们将它们命名为LoginView
和LoginPresenter
。此外,我们还将为Interactor类定义一个接口,LoginInteractor
LoginActivity
引用了LoginPresenter
,所有逻辑都将在这里处理。具体的实现,loginPresentImpl
参考了LoginView
和LoginInteractor
。interactor的具体实现,LoginInteractorImpl
将使用活动上下文初始化Android特定资源,这些资源是收集登录过程中所需数据所必需的
这样,演示者的逻辑对于android资源仍然是不可知的,并且可以很容易地进行单元测试
示例代码片段(请注意,演示者如何只知道抽象交互者。具体交互者在视图中初始化,提供其活动上下文。)
首先,我们为所有类定义契约:
interface LoginView {
fun onLoginSuccess()
fun onLoginFailed()
fun showErrorMessage(error: String)
//...........
}
interface LoginPresenter {
fun proceedLogin(username: String, password: String)
//............
}
interface LoginInteractor {
fun getUserByUsername(username: String) : User
fun getUserCredentials() : Credential
//............
}
然后,他们的具体实施:
class LoginActivity : LoginView, AppCompatActivity() {
private lateinit var presenter: LoginPresenter
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_login)
// initialize presenter
presenter = LoginPresenterImpl(
view = this,
interactor = LoginInteractorImpl(this)
)
// your code goes here
}
override fun onLoginSuccess() {
// your code goes here
}
override fun onLoginFailed() {
// your code goes here
}
override fun showErrorMessage(error: String) {
// your code goes here
}
}
class LoginPresenterImpl(
private val view: LoginView,
private val interactor: LoginInteractor
) : LoginPresenter {
override fun proceedLogin(username: String, password: String) {
// your custom login logic goes here
// call interactor to get data
// process data
// give feedback to view
}
}
class LoginInteractorImpl(context: Context) : LoginInteractor {
override fun getUserCredentials() {
// your code goes here
}
override fun getUserByUsername(username: String) {
// use context to access local DB...
}
}
注意:为了更好地分离关注点,使用依赖项注入解决方案可以消除由于视图正在初始化所有其他对象而产生的问题。使用使用活动上下文作为实现细节的类。创建一个类,接收上下文作为构造函数参数,公开一个不了解上下文的方法,然后在您的演示者或任何您接收到的类中,而不是直接在上下文中公开。您能给我一个您想要实现的用例吗?我个人将与活动相关的值作为构造函数传递,而不是上下文。@ManojPerumarath,类似于MVP模型中的Context.getSystemService()。用于检查互联网连接。我所做的是创建用于网络检查的UTIL,并在调用presenter方法之前使用它,我认为使用它不会违反使用MVPI的规则。这里有两个问题-a)LoginInteractorImpl是MVP模型,您在那里使用了上下文。我的困惑就在这里,这不是意味着(上下文)在模型中使用android术语吗?b) 您在MVP视图(活动)中创建了LoginInteractorImpl的引用,它不是在模型和视图之间创建了链接吗?我是MVP新手&不理解这两点。是的,你说得对。为了更好地分离关注点,应该使用工厂方法和依赖项注入工具,如或。在某些情况下,使用上下文是不可避免的,尤其是当您的数据源是特定于android的资源时。这样做的方法是将具体的实现隐藏在抽象类/接口后面。您将上下文传递给interactor,这还不错,因为它没有存储为属性。但就单元测试而言,通过与特定案例更相关的测试可能更好。若您使用上下文来检索字符串,那个么您可以定义LocalizationProvider或StringProvider,并将其传递到interactor中。在测试中进行模拟会更容易,而且层分离也会更好。