MVP模型应该包含特定于Android的术语吗?

问题描述 投票:3回答:1

我可以在MVP视图中做逻辑事情,但据我所知,根据MVP模式,视图应尽可能愚蠢。 MVP模型可以包含Android特定术语吗?如果没有,那么我如何在MVP模型中使用活动上下文?

android android-context android-mvp
1个回答
2
投票

让我们假设基于MVP模式的Login功能的实现,其中模型(LoginInteractor)将使用活动上下文。

因此,我们必须实现以下类:LoginActivityLoginPresenterImplLoginInteractorImpl(作为MVP模型)。正如MVP所述,我们将在View和Presenter之间定义一个契约。我们将它们命名为LoginViewLoginPresenter。此外,我们还将为Interactor类LoginInteractor定义一个接口。

LoginActivity引用了LoginPresenter,其中所有逻辑都将被处理。具体实现,LoginPresenterImpl参考了LoginViewLoginInteractor。交互器的具体实现LoginInteractorImpl将使用活动上下文来初始化收集登录过程中所需数据所必需的Android特定资源。

这样,演示者逻辑对于android资源仍然是不可知的,并且可以很容易地进行单元测试。

示例代码片段(请注意,演示者如何仅知道抽象的Interactor。具体的交互器在视图中初始化,提供它的活动上下文。)

首先,我们定义所有类的合同:

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...
    }
}

注意:为了更好地分离关注点,使用依赖注入解决方案可以消除View正在初始化所有其他对象的问题。

© www.soinside.com 2019 - 2024. All rights reserved.