One of the ways that the MVP framework maximizes the possible connectivity to different domain model objects is by the introduction of the ValueModel hierarchy of classes. A ValueModel wraps an object (its value) and provides a simple, generic interface onto this for its clients. All ValueModels provide the same interface, that is, a client uses #value: to set the value and #value to get it. Because of this, the client does not need to know where the value comes from or how it is actually accessed. Since ValueModels are models they are capable of supporting observers onto them. To this end they trigger a #valueChanged notification whenever the value that they wrap is changed.
There are a number of different types of ValueModel available; take a look at the ValueModel hierarchy of classes. Perhaps most important, however, are the ValueHolder and ValueAspectAdaptor.
A ValueHolder can be used to wrap any object to make it appear as a value. A ValueHolder can easily be created onto any object by sending it the message #asValue. This creates and answers the new ValueHolder model that wraps the object. Clients can set the value, thereby replacing the wrapped object, using #value: and they can retrieve it using #value.
Try this. Wrap a String with a ValueHolder and access it as a value.
vm := 'Hello' asValue.
vm value. "Display it"
vm value: 'Hello again'.
vm value. "Display it"
A ValueAspectAdaptor can be used to adapt any aspect of an object to make it appear as a value. An aspect is considered to be any pair of similarly named accessor methods such as #extent and #extent:. You can create a ValueAspectAdaptor easily onto a particular aspect of an object using the #aspectValue: message.
Try this. Create a shell window and allow its caption to be wrapped with a ValueAspectAdaptor and modified through it. Evaluate the falling lines individually.
s := Shell show.
vm := s valueAspect: #caption.
vm value: 'A new caption'.
Keep the example shell window open and now to demonstrate the pluggable nature of ValueModels, we'll plug a Prompter onto the caption aspect adapter just created and allow the caption to be directly edited.
Prompter on: vm prompt: 'Enter a caption' caption:
'Example'
The simplicity of the in-protocol (#value and #value:) and the out-protocol (#valueChanged) means that a ValueModel is very flexible when used in a pluggable framework such as MVP. Indeed, they are so commonly used that Dolphin has specific subclasses of presenter and view to support them. These are ValuePresenter and ValueConvertingControlView respectively. Both of these expect some sort of ValueModel as their model. The ValueConvertingControlView also adds a type converting operation as another level of indirection between the actual model object and the view's requirements of it. This further increases the flexibility as to what sorts of view can be connected to what sorts of model.