Object-Oriented Design – Use of Association, Aggregation, and Composition

encapsulationobject-oriented

I have gone through lots of theories about what is encapsulation and the three techniques of implementing it, which are Association, Aggregation and Composition.

What I found is:

Encapsulation

Encapsulation is the technique of making the fields in a class private and providing access to the fields via public methods. If a field is declared private, it cannot be accessed by anyone outside the class, thereby hiding the fields within the class. For this reason, encapsulation is also referred to as data hiding.

Encapsulation can be described as a protective barrier that prevents the code and data being randomly accessed by other code defined outside the class. Access to the data and code is tightly controlled by an interface.

The main benefit of encapsulation is the ability to modify our implemented code without breaking the code of others who use our code. With this feature Encapsulation gives maintainability, flexibility and extensibility to our code.

Association

Association is a relationship where all object have their own lifecycle and there is no owner. Let’s take an example of Teacher and Student. Multiple students can associate with a single teacher and a single student can associate with multiple teachers, but there is no ownership between the objects and both have their own lifecycle. Both can create and delete independently.

Aggregation

Aggregation is a specialized form of Association where all objects have their own lifecycle, but there is ownership and a child object cannot belong to another parent object. Let’s take an example of a Department and teacher. A single teacher cannot belong to multiple departments, but if we delete the department the teacher object will not be destroyed. We can think of it as a “has-a” relationship.

Composition

Composition is again a specialized form of Aggregation and we can call this as a “death” relationship. It is a strong type of Aggregation. Child object does not have their lifecycle and if parent object deletes all child object will also be deleted. Let’s take again an example of relationship between House and rooms. House can contain multiple rooms but there is no independent life of a room and any room cannot belong to two different houses. If we delete the house, the room will automatically be deleted.

The question is:

Now these all are real world examples. I am looking for some description about how to use these techniques in actual class code. I mean what is the point for using three different techniques for encapsulation, How these techniques could be implemented and How to choose which technique is applicable at time.

Best Answer

The distinction between association, aggregation and composition as you describe it is a legacy going back to the old times of manual memory management. For example in C++ the memory used by objects has to be manually released and it is thus paramount to carefully design the lifecycle of composed objects. While the distinction between aggregation and composition is still being taught by many text books, it is essentially irrelevant when programming in environments with automatic memory management. If you have garbage collection all of them are just composition, period.

Encapsulation on the other hand is a much more general principle than what you describe. It is foremost the idea of bundling data and the functions that operate on this data in one module. One way to implement this is by keeping the state of the module private and expose changes to that state through public services. So client cannot access the state on their own but have to tell the module their intend by sending messages. So encapsulation is not limited to objects but applies to services as well. Actually, one way of looking at objects is to look at them as services.

Here's an example of encapsulation

public class Counter {
    private int n = 0;
    public int inc() { return n++; }
}

or the same using lambda functions

var counter = (function() {
    var n = 0;
    var inc = function() { return n++; }
    return inc;
})();

In both cases the data, that is the variable n, is bundled together with the function inc that operates on it. And there is no way any other function could ever access n, thus we have an encapsulated module that provides counting as a service.

NB: exposing all of an object's inner state through accessors is actually a violation of encapsulation. Alas, it is such a common violation that many will confuse it with good object-oriented design.