Navigation:  Appendix B: Dolphin Pattern Book > Class Patterns >

Property

Previous pageReturn to chapter overviewNext page

Context

You are creating a New Class and choosing Instance Variable Roles. Sometimes you may come across occasions when some state instance variables are not applicable to all instances of a class or are rarely used. Using an instance variable to hold the attribute then this will waste space in all the instances for which the attribute has no relevance.

What can be done to reduce this overhead in situations where it may not be appropriate or convenient to refactor the class hierarchy?

Solution

Dolphin Smalltalk provides a Property mechanism for such eventualities. This allows you to associate data with an object on a per-instance basis.

Property accessing is provided for all objects by a number of methods in class Object. Look in the properties category to see the available methods. In particular, the following methods are most important:

propertyAt: aSymbol

propertyAt: aSymbol put: anObject

removePropertyAt aSymbol:

Before using a property, however, check that there isn't a better way to structure your classes to avoid the issue. Refactoring so that there is a new subclass containing an instance variable for the additional attribute is often a more appropriate solution. Use the property mechanism only once you are satisfied that there is a genuine case that requires it.

Example

Consider an architectural application. It contains a hierarchy of classes (eg. Shape) representing the various elements in a drawing. Some attributes are common to all of the subclasses, eg. size, position, and these are instance variables. There may also be a label attribute which is common, but optional. This could be implemented as a property.

Shape>>label

  "Private - Answer the label belonging to the receiver,

  or nil if the receiver has no label associated with it."

  ^self propertyAt: #label ifAbsent: []

 

Shape>>label: aString

  "Private - Set the label belonging to the receiver."

  ^self propertyAt: #label put: aString

 

Consequences

Using a property to hold attribute information for an object can save space in situations where the majority of instances of a class do not actually make use of the attribute. However, the standard property accessing mechanism is much slower than accessing an instance variable and the amount of memory required to store a property is greater.

When using the property mechanism instead of holding data in an instance variable remember that this is an implementation detail and should be hidden from clients of the class, and even other methods in the class itself. You should always provide accessor methods to get and set an attribute which has been implemented as a property.

Related Patterns

Accessor Method, Instance Variable Role