20

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.

  • 1
    Please note that Aggregation, Composition and Association are not techniques to implement encapsulation. An encapsulation can also exist even if there is just one class/object. Encapsulation is just an essential feature to in Object Orientation to hide your object's data. – Maxood Nov 22 '13 at 21:24
  • 1
    "A single teacher can NOT belongs to multiple departments" really? Didn't you notice your resource modified the content ? – KNU Feb 12 '15 at 8:04
  • I've managed to use Composition to identify DDD Aggregate Roots and their Entities when doing Domain-Driven Design. A new use for an old convention. – Jonn Mar 14 '16 at 1:59
12

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.

  • 2
    Automatic Memory Management has nothing to do with object relationships. An object diagram itself tells the programmer how to code the classes, their interfaces and their methods as per the requirements of the system under consideration. – Maxood Nov 22 '13 at 21:21
  • 2
    There's also a consideration outside of memory. In data design or perhaps serialization. In composition, you may need to have different foreign key constraints in a RDBMS, or possibly change how you handle serialization of an object if it has composite children versus aggregate children or associated objects. – Chris Jun 15 '15 at 17:17
8

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.

    public class Test{

    private String name;

       private int age;

       public int getAge(){
          return age;
       }

       public String getName(){
          return name;
       }
    }

Refer this question also.

Association indicates the relationship between objects. eg: Computer uses keyboard as input device.

An association is used when one object wants another object to perform a service for it.

Aggregation is a special case of association. A directional association between objects. When an object ‘has-a’ another object, then you have got an aggregation between them.

eg: Room has a table, but the table can exist without the room.

    class Room {

      private Table table;

      void setTable(Table table) {
        this.table = table;
      }

    }

Composition is a special case of aggregation. Composition is more restrictive. When there is a composition between two objects, the composed object cannot exist without the other object. This restriction is not there in aggregation. eg: rooms in a house, which cannot exist after the lifetime of the house.

    class House {

      private  Room room;

      House(Room roomSpecs) {
        room = new Room(roomSpecs);
      }

    }

Composition is a design technique to implement has-a relationship in classes, either by Inheritance or object Composition for code reuse.

One of the best practice in Java programming is to use composition over inheritance

  • how does this answer the question asked? – gnat Nov 22 '13 at 10:32
1

Using those techniques usually results in design practices like SOLID or various design patterns.

The point of using patterns, practices and such is to describe a solution to a specific problem that is also maintainable and extensible. You simply need to get enough experience to tell where to use which pattern or technique.

1

I frankly feel that these notions being taught at academic do have their importance in the contexts of object orientation and class design. These concepts aid us a lot when it comes to modelling a system from the scratch. Association, Aggregation and Composition belong exclusively to UML's class diagram and are completely independent of technology constraints like memory issues.

Furthermore, you also have to consider the higher level or business goals of the system you are modelling. We have objects like House and Room in our system under consideration, but cannot be strongly related (via composition). For instance, if I am modelling a real estate system then I might have to know what room belongs to what house. But lets that I am modelling a surveying or census system where i want to know how many people are living in each room of the house in a certain area, then I just do not need to relate a room with a house via composition.

Another example could be of an orchard and certain kind of fruit. Lets say I can only consider an orchard when I have apple trees planted inside it. The bottom line is that the requirements of the overall system does matter a lot.

Encapsulation is one of the pillars of Object Oriented Design. You need to bundle your data and the operations you will perform on your data. also you have to hide certain attributes of your object from the outer world in order to enable that object to survive in a valid state. When 2 objects are interacting, they have to interact each other via an interface. And that's what encapsulation ensures about when we design our OO system.

Here is how these concepts are applied to the code:

ASSOCIATION: Association indicates the relationship between objects. It lets the programmer know what methods to write in their classes to make them interact with each other. You can find several examples of code and class diagrams to understand association. In your example of Teach and Student, there is a relationship of teaching and taught by. So you will simply write a set of methods (technically called interface) via which you can get to know which student has what teachers and which teacher has what students. Association also enables the system modeller to aid the database designer about the attributes and fields that need to be kept in the database.

COMPOSITION: If one object is an integral part of another object, then i might have to indicate this relationship in the constructor of the other object. For example, in your scenario of Houses and Rooms we can write the following code in case we want to know which room belongs to what house type.

class House{
          string _HouseType;   
     public:    
    void setHouseType(string house_type)
     {
        this. _HouseType = house_type;
     } 

     string getHouseType()
    {
       return _HouseType;
    }
};



 House HouseObject = new House();


class Room{

 public: 
 Room(string HouseType) {
       this._HouseType = HouseObject.getHouseType();  //as in my system a room cannot exist without a house

 } 

};

The programmer will also ensure while invoking destructors of the object, that the other object's destuctor also gets invoked. This is crucial.

AGGREGATION: Lets say if the relationship between objects is weak then we for the programmer, it would mean to use an instance variable instead to indicate the relationship. And then write a mutator functon (setter) to provide value to that object from another one.

class Department{

 string dept_name;

public:
   void setDeptName(string name)
   {
        this.dept_name=name;
   }

   string getDeptName()
   {
        return dept_name; 
   }

};



 Department DepartmentObject = new Department();

class Teacher{

 string dept_name;

public:

  setDeptName(string name)
  {
     this.dept_name = DepartmentObject.getDeptName();  //You only need to invoje this method when needed (aggregation)
  }
}

};
1

OK, let's map this to some core properties rather than abstract concepts that only make sense once you understand what they mean. Like some commenters I do not agree with the accepted answer, I say these are concepts independent of memory management.

Encapsulation

You want to hide complexity from the client, only publishing the stuff that matters from the client's point of view, making things easier for the client. As a bonus you get the certainty that nothing can mess with the encapsulated code. As long as you respect the interface and the functionality, you can rework stuff and rest assured you will not break anything. The dependency is on the published interface only.

Encapsulation is one of the main pillars of object orientation. It it not a pattern, it is a principle and it may apply to logic and data alike. It is just a basic benefit of using classes in the first place, not something you would see explicitly stated in a diagram or design document.

Association

This is a very loose concept that basically describes just a dependency between objects. One object knows about the existence of another object and may use its functionality at some point. In a diagram the association would alert you that there is a dependency and that changing one object may impact the other. It is not a technique to apply when you have some problem to solve, it is more like a fact of life you should be aware of when it is there. It is a relationship. Like an invoice having an Orders property. Both Order and Invoice have their own life cycle. One is about goods and the other is about payment, which essentially makes them independent but it is important to know what goods are being payed for.

Containment

I am adding this because it belongs in the series and will make aggregation more meaningful. I do not hear the term being used in a SE context a lot anymore but I think it is still useful. Containment implies encapsulation but is strictly about object instances private to the containing class. The functionality of the contained objects is selectively exposed through public interfaces. The containing class controls the life cycle of the controlled objects. You use this when you need some features of an existing class to make the containing class functional. This could be an XML parser and the client of the containing class may never see or know anything related to XML. As a metaphor, think of the contained object as a back office worker. Clients never meet these people yet they are needed to provide the service.

Aggregation

This is a lot like containment except for the life cycle control and visibility of the aggregated objects. The aggregated objects are already available in a different context and are managed by a different entity. The aggregator is merely offering a facade, a portal to the aggregated objects. When the client addresses the aggregate, it gets the interface of the aggregate object itself, not a wrapper around it. The point of the aggregate is offering a logical grouping of things. Think of an access point to services or some other wrapper object.

Composition

It seems to me this is the more contemporary term for containment, possibly because it was coined in a popular book of relatively recent origin. Where containment focusses on the technical aspects of object relationships, composition is typically used in the context of design decisions, more specifically as a more flexible alternative for inheritance.

It does not say much about the nature of object relationships or ownership, it merely indicates that functionality is implemented by combining the functionality of existing classes. Therefore I would argue it does not belong in this series because it does not say anything about the technical aspects of an implementation where the others do.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.