patternkotlinMinor
Observer pattern using a set of observers and delegated properties
Viewed 0 times
observerspropertiesobserverdelegatedpatternusingandset
Problem
The idea is to implement the observer pattern, with a separate notification method for each observed property of the observed object. Let me start with a simplified use case:
I'm new to Kotlin, so I'd like some feedback on the following implementation:
```
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty
/**
* A set of observers for a particular object, to easily implement the Observer Pattern without needing inheritance.
*
* This can be made a public property of the object. Call [observe] to create delegated properties for each property
* that observers need to be notified about.
*
* @param O The type of the observers, typically an interface.
*/
class ObserverSet {
private val observers = mutableSetOf()
private val properties = mutableListOf>()
/**
* Sets whether an observer is present in the set. If the observer was actually added to the set, its notification
* methods will be called with the current value of the property.
*
* @param observer The observer.
* @param present If true, the observer will be added to the set if not already there. If false, the observer will
* be removed from the set if it's there.
*/
fun toggle(observer: O, present: Boolean) {
if (present) {
val wasPresent = observer in observers
observers.add(observer)
if (!wasPresent) {
init(observer)
}
} e
class Point {
val observers: ObserverSet()
val x by observers.observe(0f, PointObserver::xChanged)
val y by observers.observe(0f, PointObserver::yChanged)
}
interface PointObserver {
fun xChanged(old: Float, new: Float)
fun yChanged(old: Float, new: Float)
}
class PointView(point: Point) {
init {
point.observers.add(object : PointObserver {
override fun xChanged(old: Float, new: Float) { ... }
override fun yChanged(old: Float, new: Float) { ... }
})
}
}I'm new to Kotlin, so I'd like some feedback on the following implementation:
```
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty
/**
* A set of observers for a particular object, to easily implement the Observer Pattern without needing inheritance.
*
* This can be made a public property of the object. Call [observe] to create delegated properties for each property
* that observers need to be notified about.
*
* @param O The type of the observers, typically an interface.
*/
class ObserverSet {
private val observers = mutableSetOf()
private val properties = mutableListOf>()
/**
* Sets whether an observer is present in the set. If the observer was actually added to the set, its notification
* methods will be called with the current value of the property.
*
* @param observer The observer.
* @param present If true, the observer will be added to the set if not already there. If false, the observer will
* be removed from the set if it's there.
*/
fun toggle(observer: O, present: Boolean) {
if (present) {
val wasPresent = observer in observers
observers.add(observer)
if (!wasPresent) {
init(observer)
}
} e
Solution
-
You don't need a
-
Sometimes in Kotlin you don't have to declare temporary variables so that you can do something with a return value before returning it. e.g.:
Unfortunately this can sometimes look a bit strange using
-
You might want to take a look at Delegates.observable - stdlib - Kotlin Programming Language which you may be able to reuse to improve and reduce your code.
You don't need a
wasPresent variable. MutableSet.add returns true if the element was added to the set:if (observers.add(observer)) {
init(observer)
}-
Sometimes in Kotlin you don't have to declare temporary variables so that you can do something with a return value before returning it. e.g.:
return ObservedProperty(initialValue, onChanged).apply { properties.add(this) }Unfortunately this can sometimes look a bit strange using
this, etc. but in Kotlin 1.1 you can use bound callable references:return ObservedProperty(initialValue, onChanged).apply(properties::add)-
You might want to take a look at Delegates.observable - stdlib - Kotlin Programming Language which you may be able to reuse to improve and reduce your code.
Code Snippets
if (observers.add(observer)) {
init(observer)
}return ObservedProperty(initialValue, onChanged).apply { properties.add(this) }return ObservedProperty(initialValue, onChanged).apply(properties::add)Context
StackExchange Code Review Q#155580, answer score: 6
Revisions (0)
No revisions yet.