Transformation Interface Page 7 21/08/01
placed in client code, manager objects, constructor methods or separate methods (static or
otherwise), depending on the circumstances. In the example presentation layer shown later in
this paper (figure 6), the adaptor class which implements the Transformation Interface creates
the form in its contructor method.
Attribute Mapping
The key issue in a two-way mapping is how to send the data (attributes of an object) from one
layer or format to another. This is handled by the code in the transformation methods – that is
the sole purpose of transformation methods. The implementing programmer needs to type in
the necessary code to painstakingly map each attribute of the object onto the other format.
The code in the transformation methods can be relatively straightforward or can encapsulate
and hide the possibly fiddly details of the transformation.
Encapsulating complex mappings
One of the benefits of complete transparency of implementation is the ability to encapsulate
any messy mapping code under the ultra-simplicity of a pair of transformational methods.
For example, a load transformational method, when reading an integer field from a
database, may need to validate that the value makes sense then map/cast it into an enumerated
type that the business object actually uses. The transformational method in the other direction
will map the enumerated type back into a regular integer to be stored in the database.
Similarly, a pair of GUI transformational methods would contain the either straightforward or
fiddly code to represent object attributes in widgets of some sort, and back again – the details
of which will vary depending on the GUI widgets involved.
Furthermore, complex mappings might require that aspects of a single object attribute be
displayed in separate GUI widgets. Conversely, a number of object attributes might be
combined and displayed in a single GUI widget (e.g. a series of numbers plotted on a
graph/canvas widget). Whether the code is simple or complex, it is encapsulated in the
transformational methods, and the programmer knows where to go to modify and control the
mapping behaviour.
Foreign keys and pointers
A further example of how transformation methods can encapsulating complex mappings is the
case of say, loading a composite object from a database. The .LoadFromDb transformation
method for the composite class e.g. Customer would house the code necessary to convert,
the database table record into an object. Any aggregated sub-object e.g. CustomerAddress
would be referred to using a foreign key (an integer id). So in order to fully construct the
composite domain object e.g. Customer, both the actual object (Customer ) and the object it
aggregates (CustomerAddress ) will need to be created and a pointer set from the
composite object to the aggregated sub-object. In addition, a number of database queries need
to be made in order to extract all the necessary data for both CustomerAddress and
CustomerAddress. The transformation method can encapsulate all that needs to be done.
Note that ideally, such transformational methods would typically call other transformational
methods to load in the sub-objects rather than trying to do everything themselves – this is just
common sense factoring. e.g. If class Customer aggregates the class CustomerAddress,
then Customer.LoadFromDb will at some stage call CustomerAddress.LoadFromDb.
One needs to be careful to transform/load objects in the right order, since loading one object
may rely on another object already being loaded. Some of the considerations discussed here