假设我要使用MVP(在Android上会更详细)。有关如何执行此操作的文章很多。但是,尚不清楚如何在其中添加应用特定的逻辑?
示例:我想让用户键入host和port并使用该数据创建app-global服务器api impl(比如说Retrofit实例)。
所以我有Contract和Base ..接口:
/**
* MVP : Presenter (Passive View flavor)
*/
interface Presenter : BasePresenter<View>
/**
* MVP : View (Passive View flavor)
*/
interface View : BaseView<Presenter> {
var host: String
var port: String
fun showValidationError(error: Exception)
}
interface BasePresenter<ConcreteView> {
fun onModelChanged()
fun onViewChanged()
fun attachView(view: ConcreteView)
fun detachView()
}
interface BaseView<ConcretePresenter> {
var presenter: ConcretePresenter?
}
型号:
/**
* MVP : Model
*/
class Model(
_host: String = "",
_port: UInt = 0U) {
// we could add presenter notification on both `host` and `port` changed,
// but we need it to be notified once only when both are set
var host = _host
private set
var port: UInt = _port
private set
fun update(host: String, port: UInt) {
this.host = host
this.port = port
presenter?.onModelChanged()
}
var presenter: Presenter? = null
}
演示者:
class PresenterImpl(val model: Model) : Presenter {
private var view: View? = null
override fun attachView(view: View) {
if (this.view != null) {
detachView()
}
this.view = view
this.view?.presenter = this
updateView()
}
private fun updateView() {
view?.let {
it.host = model.host
it.port = model.port.toString()
}
}
// as Model observer
override fun onModelChanged() {
view?.let { updateView() }
}
// as View observer
override fun onViewChanged() {
view?.let {
if (!isValidView(it)) {
return
}
model.update(it.host, it.port.toUInt())
}
}
private fun isValidView(view: View): Boolean {
try {
if (view.host.isEmpty())
throw Exception("Host can not be empty")
if (view.port.isEmpty())
throw Exception("Port can not be empty")
if (view.port.toUIntOrNull() == null)
throw Exception("Port is expected to be positive Number")
} catch (e : Exception) {
view.showValidationError(e)
return false
}
return true
}
override fun detachView() {
view?.presenter = null
view = null
}
}
为简单起见,我们将“活动”用作“视图”隐式实现,并且所有内容都链接在一起(模型表示者视图)。
这是流程:
onViewChanged
通知Presenter view.host
和view.port
)请求数据,对其进行验证并使用model.update()
更新模型。onModelChanged()
通知Presenter 第5步可以作为第3步的延续(而不是作为模型的侦听器)完成,但是它并没有明显改变。
最好的方法是什么?
这些选项是:
onModelChanged()
(不想仅仅使用继承)onModelChanged()
中更改模型时通知他们 Presenter impl位于不依赖于Android的不同Gradle模块中,因此我不能只在onModuleChanged()
的{{1}}中添加此应用专用代码。