处理 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 周围添加可变包装器的劣势之间取得平衡。但那是你的决定;取决于您的上下文。
我有一个基于 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 周围添加可变包装器的劣势之间取得平衡。但那是你的决定;取决于您的上下文。