** Table of Contents ** As the name implies, this pattern is to eliminate the relationships between objects through the mediator class.
I often see specifications such as the button not being enabled unless the text box has a value. This cannot be achieved unless the textbox object knows the button object (and holds it as an instance variable). With such a simple specification, it may not be a problem if it is directly related, but for more complicated functions, a class must know a number of objects. Eliminate it using the intermediary class.
After all, any pattern results in increased orthogonality.
Define an object that encapsulates the interaction of a group of objects. The Mediator pattern helps reduce coupling by preventing objects from explicitly referencing each other. This allows the interaction of objects to be changed independently.
Mediator abstract class ・ ConcreteMediator concrete class ・ Colleague Objects that you want to associate with various objects
Implements checkboxes, text boxes, and button objects. The text box cannot be entered unless one of the check boxes is checked. The button cannot be pressed unless the check box is checked and the text box is empty.
Mediator.kt
package mediator
interface Mediator {
    /**
     *Whether the button can be pressed
     */
    fun buttonPress(): Boolean
    /**
     *Whether text box can be entered
     */
    fun inputTextBox(): Boolean
}
ConcreteMediator.kt
package mediator
class ConcreteMediator: Mediator {
    var checkBox: CheckBox? = null
    var textBox: TextBox? = null
    var button: Button? = null
    override fun buttonPress(): Boolean {
        return checkBox?.sex != null && textBox?.value?.isNotEmpty() ?: false
    }
    override fun inputTextBox(): Boolean {
        return checkBox?.sex != null
    }
}
Abstract class
Colleague.kt
package mediator
interface Colleague {
    enum class Type {
        CheckBox,
        TextBox,
        Button
    }
    val type: Type
    val mediator: Mediator
}
Concrete class ·Checkbox
CheckBox.kt
package mediator
    class CheckBox(override val mediator: Mediator): Colleague {
    override val type = Colleague.Type.CheckBox
    enum class Sex {
        Male,
        Female
    }
    var sex: Sex? = null
    fun select(sex: Sex) {
        this.sex = sex
    }
}
·Text box
TextBox.kt
package mediator
class TextBox(override val mediator: Mediator): Colleague {
    override val type = Colleague.Type.TextBox
    var value = ""
    fun input(value: String) {
        if (mediator.inputTextBox()) {
            this.value = value
            println("Text box input successful")
        } else {
            println("Text box input failure")
        }
    }
}
·button
Button.kt
package mediator
class Button(override val mediator: Mediator): Colleague {
    override val type = Colleague.Type.Button
    fun press() {
        if (mediator.buttonPress()) {
            println("Button press successful")
        } else {
            println("Button press failure")
        }
    }
}
Client.kt
package mediator
class Client {
    init {
        val mediator = ConcreteMediator()
        val checkBox = CheckBox(mediator)
        val textBox = TextBox(mediator)
        val button = Button(mediator)
        mediator.checkBox = checkBox
        mediator.textBox = textBox
        mediator.button = button
        //Text box input Failed because the check box is not selected
        textBox.input("Yamada Taro")
        //Checkbox selection
        checkBox.select(CheckBox.Sex.Female)
        //Button press Failure because no text box has been entered
        button.press()
        //Text box input successful!!!
        textBox.input("Hanako Yamada")
        //Button press successful!!!
        button.press()
    }
}
[out-put]
Text box input failure
Button press failure
Text box input successful
Successful button press
that's all
Recommended Posts