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

时间:2017-03-30 07:23:15

标签: oop immutability observer-pattern

我有一个基于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标题已更改?

1 个答案:

答案 0 :(得分:1)

显然,这两个概念在这里并没有很好地结合在一起。

用户界面元素的本质是:它们允许更改。用户不知道(或关心)底层对象是否是不可变的。他想改变那个头衔。

因此,您有两种选择:

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

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

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