# Common Design Considerations for Object Properties

I’m pleased to introduce guest blogger Dave Foti. Dave has worked on MATLAB for over 15 years and currently manages the group responsible for object-oriented programming features in MATLAB. He is interested in giving MATLAB users the tools to meet increasingly complex challenges. This post will take a look at making use of object properties in MATLAB.

### Property Basics

Properties are how MATLAB objects store data. At their most basic level, properties provide a way to define what data are required for a particular kind of object. For example, if I have a set of measurements and each measurement has the same pieces of information, then I can create a class of measurement objects with a property to store each piece of information as in:

type surfaceTempReading1
classdef surfaceTempReading1
properties
Date
Latitude
Longitude
Temperature
end
end


I might have an instance that looks like this:

t1 = surfaceTempReading1;
t1.Date = date;
t1.Latitude  = '42:16:4 N';
t1.Longitude = '71:20:2 W';
t1.Temperature = 260;
disp(t1);
  surfaceTempReading1

Properties:
Date: '16-Mar-2011'
Latitude: '42:16:4 N'
Longitude: '71:20:2 W'
Temperature: 260


The MATLAB documentation describes properties here.

### Dependent Properties

In simple cases like this, it is probably fine to have all properties directly store and retrieve data. However, MATLAB provides ways to define properties that don’t directly store data. These dependent properties are defined using the Dependent attribute as in:

type surfaceTempReading2
classdef surfaceTempReading2
properties
Date
Latitude
Longitude
Temperature
end

properties(Dependent)
Altitude
end

methods
end
end
end


In this case, if I have a data set of surface temperature readings, I just need latitude and longitude to identify where the temperature was sampled. However, in analyzing the data, it might be helpful to correlate temperatures with surface altitude. Rather than have to input this data, the altitude can be calculated from a database of Earth surface topography. Assume I have a function that can provide such a value called lookupAltitude, then I can invoke that function from the Dependent property called Altitude.

t2 = surfaceTempReading2;
t2.Date = date;
t2.Latitude  = '42:16:4 N';
t2.Longitude = '71:20:2 W';
t2.Temperature = 260;
disp(t2)
  surfaceTempReading2

Properties:
Date: '16-Mar-2011'
Latitude: '42:16:4 N'
Longitude: '71:20:2 W'
Temperature: 260
Altitude: 342


### Changing Property Names

Dependent properties allow me some flexibility to implement the same external interface in different ways. A user of our class doesn’t necessarily need to know how altitude was determined or whether or not it is actually stored in a class instance. This flexibility can be useful in evolving a class over time while not breaking scripts and functions that might use the class. For example, if I decide that TimeStamp is a better name for the Date property, I can gradually start switching over to the new name without immediately changing all of the code I have using Date:

type surfaceTempReading3
classdef surfaceTempReading3
properties
TimeStamp
Latitude
Longitude
Temperature
end

% Deprecated property names
properties(Dependent, Hidden)
Date
end

methods
end

end
end
end


When I change my class as above, not only will old scripts using Date continue to work, but old MAT-Files saved using the old class definition will automatically load the Date value into the new TimeStamp property. I use the Hidden attribute so that the old property name doesn’t show up in object display, the properties command, or tab completion.

t3 = surfaceTempReading3;
t3.Date = date;
disp(t3);
  surfaceTempReading3

Properties:
TimeStamp: '16-Mar-2011'
Latitude: []
Longitude: []
Temperature: []


### Side Effects and Validation

Dependent properties can also be useful any time a property has side effects – when for example changing a property triggers an update to some other object or graphic or when getting a property requires doing some expensive operation to acquire or validate the result. Often these expensive operations can be avoided from certain "trusted" code defined inside the class. Having a one private property that doesn’t perform any side effects allows the trusted code to work on the raw property value. Other code inside and outside the class can use a public and dependent property that performs the side effects or expensive operations. Sometimes the expensive operation is just validating the input value being assigned to the property. For example, in our class if I want to validate temperature values, I can do something like the following:

type surfaceTempReading4;
classdef surfaceTempReading4
properties
Date
Latitude
Longitude
end
properties (Dependent)
Temperature
end

properties(Access=private)
pTemperature
end

methods
if t < 0
'Temperature must be a positive number in Kelvins.');
end
end
end
end
end


NOTE: The above example has been changed to correct an error in the original post.

t4 = surfaceTempReading4;
try
t4.Temperature = -15;
catch err
disp(err.message);
end
Temperature must be a positive number in Kelvins.


### Default Values

Classes can define default values for properties. A default value is defined by the class and each instance of the class is assigned that default value. Default values can be used when there is a constant default that can be documented with the class definition. Default values can save space in MAT-Files because defaults are saved once per class and values of properties not differing from default values don’t need to be saved. Generally speaking default values should be literal values wherever possible so that it is clear what the default is. For example:

type surfaceTempReading5
classdef surfaceTempReading5
properties
Date
Latitude = '0N';
Longitude = '0E';
Temperature = 0;
end
end


While it is possible to use the result of a function for a default value, one should avoid doing so unless the function returns a constant value. For example, it might be tempting to do something like:

type surfaceTempReading6
classdef surfaceTempReading6
properties
% Get the current date from MATLAB
Date = date;

Latitude
Longitude
Temperature
end
end


However, the problem with this is that the current date is not a constant default value that can be documented as part of the class. Moreover, since MATLAB evaluates default property expressions in class definitions only when a class is loaded or reloaded, the function call will generally happen once in a MATLAB session. Each object will get the same date stamp that was current when the class was loaded and not the current date at the time an object is created (perhaps the next day). Generally, one doesn’t want to assign a default value to a handle for a similar reason. If the intent is to make a new handle for each instance, then this handle has to be created in the constructor and not as a default value. Since defaults are the same for all instances created from a given class definition, all objects would get the same handle. For more information on handle classes, see Handle and Value Classes.

I’ve described a few uses for properties and a few common attributes, but I would be very interested in hearing how you use properties. You can post ideas here.

Published with MATLAB® 7.11

|