首页 > 解决方案 > 设计困境——背景还是契约?(Java/科特林)

问题描述

我有 a Activity、 aPresenter和 a Contract,它们都是 theActivityPresenter工具。将Activity有一些独特的 UI 内容,必须从Presenter. Presenter还必须能够调用 Activity(例如),它利用了 an也是 a的sendBroadcast()事实。ActivityContext

这是我的难题:如果我传递Context给,我将无法访问;Presenter独有的 UI 方法。Activity如果我将 传递Contract.ViewPresenter,我将无法访问需要Context. 我能想到的唯一解决方案是:

A)将ContextAND都传递Contract.ViewPresenter(始终是相同的对象,即Activity)或

B) 完全抛弃Design-by-Contract模式,直接ActivityPresenter


两者似乎都是坏主意……这里推荐的方法是什么?下面是我目前正在使用的代码的缩小版本:

活动.kt

class Activity: AppCompatActivity(), Contract.View {

    private lateinit var mPresenter: Contract.Presenter

    @BindView(R.id.textView)
    private lateinit var mTextView: TextView

    override fun onCreate(savedInstanceState: Bundle?) {
        // ...
        mPresenter = Presenter(this)
    }

    override fun updateText(text: String) {
        mTextView.text = text
    }

}

演示者.kt

// Pass Context or Contract.View as parameter to constructor?
class Presenter(private val ???: ???): Contract.Presenter {

    fun discoverService() {
        val intent: Intent = // ...

        mContext.sendBroadcast(intent)
    }

    override fun setServiceCommInfo() {
        mView.updateText(Acquiring Data from Service...)
        // ...
    }

}

合同.kt

interface Contract {

    interface View {
        updateText(text: String)
    }

    interface Presenter {
        setServiceCommInfo()
    }

}

标签: javakotlinandroid-contextdesign-by-contract

解决方案


我想出了一个比我在原始帖子中提到的两个“不那么丑”(丑是一个非常主观的术语)的解决方案。基本上这里的想法是确定

  1. mContext并且Contract.View永远是同一个对象
  2. 如果 O 实现了 I,则对象 O 被认为是接口 I 的实例

将以下代码添加到Presenter.kt将无需两次传递相同的对象:

class Presenter(private val mContext: Context): Contract.Presenter {

    private lateinit var mView: Contract.View

    init {
        if (mContext is Contract.View) mView = mContext
    }

}

推荐阅读