处理 GUI-based 应用程序中的不变性

Dealing with immutability in a GUI-based application

我有一个基于 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 方法中,通知监听器。

两个 "screens" 都有相同的 Note 实例,因此传播更改。

但是,具有不变性:

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

方法 Note.title(String) returns 新实例 Note 而不是改变状态。

那我怎么"notify"把标题改了NoteListItem

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

您 UI 上元素的本质是:它们允许 更改 。用户不知道(或不关心)底层 object 是否不可变。他想更改那个标题。

因此,您有两个选择:

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

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

现在您必须在保持节点 class 不可变的优势与在节点 class 周围添加可变包装器的劣势之间取得平衡。但那是你的决定;取决于您的上下文。