处理基于 GUI 的应用程序中的不变性



>我有一个基于 GUI 的应用程序 (Kotlin(,它由左侧的 Note 列表(它显示笔记的标题(和右侧选定的Note版本屏幕组成。

当用户在版本屏幕中修改标题时,列表项必须显示新标题。

在一个可变的世界里,我会做这样的事情:

interface Note {
    fun title(): String
    fun content(): String
    fun setTitle(newTitle: String)
    fun setContent(newTitle: String)
    fun addListener(l: Listener)
}
class NoteListItem(n: Note) : Listener {
    init { 
        n.addListener(this)
    }
    override fun onChange() { //from Listener
        repaint();
    }
    fun repaint() {
       //code
    }
}
class NoteEditionScreen(n: Note) {
    fun onTitleTextChanged(newTitle: String) {
        n.setTitle(newTitle)
    }
    //...
}

在方法Note.setTitle,侦听器会收到通知。

两个"屏幕"都有相同的Note实例,所以变化是传播的。

但是,对于不变性:

interface Note {
    fun title()
    fun content()
    fun title(newTitle: String) : Note
    fun content(newContent: String) : Note
}

该方法Note.title(String)返回Note的新实例,而不是更改状态。

在这种情况下,我如何"通知"标题已更改NoteListItem

显然,这两个概念在这里不能很好地结合在一起。

UI 上元素的本质是:它们允许更改。用户不知道(或关心(基础对象是否不可变。他想改变这个头衔。

因此,有两种选择:

  • 放弃你的节点是不可变的
  • 引入 UI 使用的抽象层

换句话说:您可以添加一个可变NodeContainer,用于在 UI 上显示不可变节点对象。

现在,您必须在保持 Node 类不可变的优点和在 Node 类周围添加可变包装器的缺点之间取得平衡。但这是你的决定;取决于您的上下文。

最新更新