|
In Object Oriented Programming, it is common to
see the composition of simple classes (and/or
instances) into a more complex one. This is a flexible
strategy for building complicated objects and object
hierachies and can function as a dynamic alternative to
multiple inheritance. There are two ways to perform
class (and/or object) composition depending on the
relationship between the composed elements:
Association and Aggregation.
An
Association is a composition of
independently constructed and externally visible parts.
When we associate classes or objects, each one keeps a
reference to the ones it is associated with. When we
associate classes statically, one class will contain a
reference to an instance of the other class. For
example:
|
Aggregation, on the other hand, implies
encapsulation (hidding) of the parts of the
composition. We can aggregate classes by using a
(static) inner class (PHP does not yet support inner
classes), in this case the aggregated class definition
is not accessible, except through the class that
contains it. The aggregation of instances (object
aggregation) involves the dynamic creation of
subobjects inside an object, in the process, expanding
the properties and methods of that object.
Object aggregation is a natural way of
representing a whole-part relationship, (for example,
molecules are aggregates of atoms), or can be used to
obtain an effect equivalent to multiple inheritance,
without having to permanently bind a subclass to two or
more parent classes and their interfaces. In fact
object aggregation can be more flexible, in which we
can select what methods or properties to "inherit" in
the aggregated object.
We define 3 classes, each implementing a different
storage method:
|
We then instantiate a couple of objects from the
defined classes, and perform some aggregations and
deaggregations, printing some object information along
the way:
|
We will now consider the output to understand some
of the side-effects and limitation of object
aggregation in PHP. First, the newly created $fs and $ws
objects give the expected output (according to their
respective class declaration). Note that for the
purposes of object aggregation,
private elements of a class/object
begin with an underscore character ("_"),
even though there is not real distinction between
public and private class/object elements in PHP.
$fs object Class: filestorage property: data (array) 0 = 3.1415926535898 1 = kludge != cruft method: filestorage method: write $ws object Class: wddxstorage property: data (array) 0 = 3.1415926535898 1 = kludge != cruft property: version = 1.0 property: _id = ID::9bb2b640764d4370eb04808af8b076a5 method: wddxstorage method: store method: _genid |
We then aggregate $fs
with the WDDXStorage class,
and print out the object information. We can see now
that even though nominally the
$fs object is still of
FileStorage, it now has the property $version, and the method store(), both defined in WDDXStorage. One important thing to
note is that it has not aggregated the private elements
defined in the class, which are present in the $ws object. Also absent is the
constructor from WDDXStorage,
which will not be logical to aggegate.
Let's aggregate $fs to the WDDXStorage class $fs object Class: filestorage property: data (array) 0 = 3.1415926535898 1 = kludge != cruft property: version = 1.0 method: filestorage method: write method: store |
The proccess of aggregation is cummulative, so
when we aggregate $fs with the
class DBStorage, generating an
object that can use the storage methods of all the
defined classes.
Now let us aggregate it to the DBStorage class $fs object Class: filestorage property: data (array) 0 = 3.1415926535898 1 = kludge != cruft property: version = 1.0 property: dbtype = mysql method: filestorage method: write method: store method: save |
Finally, the same way we aggregated properties and
methods dynamically, we can also deaggregate them from
the object. So, if we deaggregate the class WDDXStorage from
$fs, we will obtain:
And deaggregate the WDDXStorage methods and properties $fs object Class: filestorage property: data (array) 0 = 3.1415926535898 1 = kludge != cruft property: dbtype = mysql method: filestorage method: write method: save |
One point that we have not mentioned above, is
that the process of aggregation will not override
existing properties or methods in the objects. For
example, the class FileStorage
defines a $data property, and
the class WDDXStorage also
defines a similar property which will not override the
one in the object acquired during instantiation from
the class FileStorage.