Search code examples
oopimmutabilityobserver-pattern

Dealing with immutability in a GUI-based application


I have a GUI based application (Kotlin) that consists of a list of Notes to the left (it shows the note's title) and the selected Note's edition screen to the right.

When the users modify the title in the edition screen, the list item must show the new title.

In a mutable world, I'd do something like this:

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)
    }

    //...

}

Inside Note.setTitle method, listeners are notified.

Both "screens" have the same instance of Note, so changes are propagated.

However, with immutability:

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

the method Note.title(String) returns a new instance of Note instead of changing the state.

In that case, how can I "notify" to the NoteListItem the title has changed?


Solution

  • Obviously, those two concepts don't go together nicely here.

    The essence of the elements on your UI is: they allow for changes. The user doesn't know (or care) if the underlying object is immutable or not. He wants to change that title.

    Thus, there are two options for you:

    • give up on your Node being immutable
    • introduce an abstraction layer that is used by your UI

    In other words: you can add a mutable NodeContainer that is used for displaying immutable node objects on your UI.

    Now you have to balance between having the advantages of keeping your Node class immutable and the disadvantages of adding mutable wrapper thingy around the Node class. But that is your decision; depending on your context.