Understanding and Using the ValueModel Framework in VisualWorks Smalltalk


By: B. Woolf
Published in: PLoPD1
Pages: 467- 498
Category: Smalltalk ValueModel Idioms

Summary: ValueModel is a framework in VisualWorks Smalltalk. This collection describes ValueModels and how to use them.

Url: http://c2.com/ppr/vmodels.html

ValueModel is a framework in VisualWorks Smalltalk. Describes ValueModels and how to use them.

Pattern: Use a ValueModel to Generalize an Object's Aspect

Pages: 471-473

To allow one object to retrieve and change a collaborator object in a uniform way, use a ValueModel to store the value. ValueModel is an abstract class, so you'll actually use an instance of one of its concrete subclasses.

Pattern: Use a ValueModel to Share a Value

Pages: 473-474

To allow two objects to share a common value so that both can access and change it, and when one object changes it, the other is notified automatically, place the common value in a shared ValueModel. The sharing objects can register their interest, and the ValueModel will notify them when the value changes.

Pattern: Use onChangeSend:to: to Register Interests on a Value

Pages: 474-477

To allow an object using the value in a ValueModel to be notified when the value changes, to register your interest, send the ValueModel "aValueModel onChangeSend: aSelector to: aDependent", in which aSelector is the name of the method to run when the value changes, and aDependent is the object that contains the method (usually "yourself").

Pattern: Use ValueModel Chains Instead of onChangeSend:to:

Pages: 477-479

If the update performed when a change occurs is so simple that a separate "<something>Changed" method seems unnecessary, eliminate this step and use a ValueModel instead. This will connect the parent and dependent models using two ValueModels.

Pattern: Encapsulate Senders of value and value:

Pages: 479-481

When should you use "value" and "value:"? Implement separate messages for accessing an object's aspects or values and the ValueModels that contain those aspects.

Pattern: Ensure That All Objects Sharing a Value Use the Same ValueModel

Pages: 481

How can multiple objects that need to share the same value be assured of sharing a single ValueModel? When an instance variable holds a ValueModel, create a get method for it but not a set method, and initialize it in the initialize method. This will ensure that it will only be set once and never reset.

Pattern: Maintain Consistent ValueModelValue Types

Pages: 481-483

When an object gets a value from a ValueModel, how does it know the type of object it will receive? When defining a variable's type as ValueModel, also specify the type of the ValueModel's value.

Pattern: Use a ValueHolder to Hold a Stand-Alone Object

Pages: 483-484

To wrap ValueModel behavior around objects in instance variables, use a ValueHolder. It will wrap the object and give it ValueModel behavior. Store the ValueHolder in the instance variable.

Pattern: Use an AspectAdaptor to Hold an Aspect of an Object

Pages: 484-486

How can ValueModel behavior be wrapped around a retrieval of an aspect of another model? Use an AspectAdaptor. Unlike a ValueHolder, the object itself won't be wrapped with ValueModel behavior. Retrieving and storing the object as an aspect of its container model will be wrapped as a ValueModel.

Pattern: Use a BufferedValueHolder to Delay the Commit of a New Value

Pages: 486-487

When a view has a number of values, how can the user be allowed to change all of them without changing them in the ApplicationModel and then accept or cancel all the changes at once? Use a BufferedValueHolder as a layer of separation between the model and the ValueModel for a field. A regular ValueModel will immediately store a new value in the model, but the ValueModel stored inside a Buffered ValueHolder will suspend the new value until you tell it to commit to the model.

Pattern: Use a RangeAdaptor to Channel a Number's Range

Pages: 487

To convert a real-world quantity to a percentage so that when the quantity changes, the percentage is automatically recalculated, use a RangeAdaptor, a ValueModel that converts a number in a specified range into a percentage.

Pattern: Use an IndexedAdaptor to Hold a Single Index in a Collection

Pages: 488

To wrap ValueModel behavior around an element in a collection, use an IndexedAdaptor to give a collection element the aspect value.

Pattern: Use a SlotAdaptor to Hold a Single Instance Variable

Pages: 489-490

To wrap ValueModel behavior around an instance variable without changing the kind of object an instance variable holds, use SlotAdaptor to give an object's instance variable the aspect value. The SlotAdaptor will also allow the element to be shared by multiple dependents.

Pattern: Use a PluggableAdaptor to Hold Some Part of an Object

Pages: 490-491

To wrap ValueModel behavior around an arbitrary portion of an object, use a PluggableAdaptor to hold an arbitrary portion of an object when no other kind of ValueModel will work.

Pattern: Use a TypeConverter to Convert a Value Between Types

Pages: 491-492

When two objects want to share a value but each wants a different type, how can the value appear as the appropriate type for each? Use a TypeConverter to convert the type of object.

Pattern: Use a ScrollValueHolder to Hold a Position in n-Dimensional Space

Pages: 492-493

You're using the ValueModel framework. What object should keep track of how much a point's position on a grid has changed? Use a ScrollValueHolder to hold the scroll position of a point. Set the grid to be the minimum size of each step the point must take when it moves.

Pattern: Use SelectionInList to Hold a List and Its Selection

Pages: 493-494

To set up a list so it can say which item is being used, use a SelectionInList to track a list and its current selection. When you register your interest in one of its aspects, it will notify you of changes.