Composition & Aggregation - thehighestbidder/2143--Object-Oriented-Programming GitHub Wiki

Composition and Aggregation

Definition:

Composition and aggregation are two types of association relationships between objects in Object-Oriented Programming. Association represents a "has-a" relationship, where one object contains or is related to another object. Composition and aggregation differ in the strength and lifecycle dependency of this relationship.

  • Composition ("has-a" - strong relationship): Represents a "whole-part" relationship where the part cannot exist independently of the whole. If the whole object is destroyed, the part object is also destroyed. This implies a strong ownership.
  • Aggregation ("has-a" - weak relationship): Represents a "has-a" relationship where the part can exist independently of the whole. If the whole object is destroyed, the part object typically continues to exist. This implies a weaker "uses" or "is related to" relationship.

Explanation:

Understanding the difference between composition and aggregation is crucial for designing robust and well-structured object-oriented systems. Choosing the right type of association reflects the real-world relationships between entities and impacts the lifecycle management of the related objects.

Key Differences:

Feature Composition Aggregation
Relationship Strong "whole-part" Weak "has-a" or "uses"
Lifecycle Part dies with the whole Part can exist independently of the whole
Ownership Exclusive ownership of the part by the whole Shared or non-exclusive relationship; whole doesn't necessarily own the part
Creation of Part Part often created within the whole object Part can be created independently and then associated with the whole

Analogy:

  • Composition: Consider a Computer and its CPU. The CPU is an integral part of the computer; if the computer is discarded, the CPU typically goes with it. The Computer owns its CPU in a strong sense.
  • Aggregation: Consider a University and its Department. A department can exist even if the university ceases to exist (it might become part of another university or become an independent institution). The University has a Department, but it doesn't have exclusive ownership, and the department has its own lifecycle.

Code Examples (Python):

# Class representing a CPU (for Composition)
class CPU:
    def __init__(self, model):
        self.model = model

    def process_data(self, data):
        print(f"CPU ({self.model}) is processing: {data}")

# Class representing a Computer (Composition - strong relationship)
class Computer:
    def __init__(self, brand, cpu_model):
        self.brand = brand
        # The Computer creates and owns its CPU
        self.cpu = CPU(cpu_model)

    def run(self, program):
        print(f"{self.brand} computer is running: {program}")
        self.cpu.process_data(f"Instructions for {program}")

# Class representing a Department (for Aggregation)
class Department:
    def __init__(self, name):
        self.name = name

    def list_courses(self):
        print(f"Courses offered by the {self.name} department.")

# Class representing a University (Aggregation - weak relationship)
class University:
    def __init__(self, name):
        self.name = name
        self.departments = [] # University has a collection of departments

    def add_department(self, dept):
        self.departments.append(dept)

    def list_all_departments(self):
        print(f"Departments in {self.name} University:")
        for dept in self.departments:
            print(f"- {dept.name}")

# Demonstrating Composition
my_computer = Computer("Dell", "Intel i7")
my_computer.run("Web Browser")
# When my_computer object is destroyed, its CPU object will also be (implicitly) destroyed

# Demonstrating Aggregation
math_dept = Department("Mathematics")
cs_dept = Department("Computer Science")

my_university = University("Tech University")
my_university.add_department(math_dept)
my_university.add_department(cs_dept)
my_university.list_all_departments()

# math_dept and cs_dept can still exist independently of my_university
another_university = University("Science Institute")
another_university.add_department(math_dept) # math_dept is now associated with another university

math_dept.list_courses() # The department still functions

Explanation of the Code:

  • Composition (Computer and CPU):

    • The Computer class creates an instance of the CPU class within its __init__ method.
    • The CPU object is tightly bound to the Computer object. If the my_computer object is no longer referenced and garbage collected, the CPU object it contains will also be gone.
    • The lifecycle of the CPU is dependent on the lifecycle of the Computer.
  • Aggregation (University and Department):

    • The University class has a list (self.departments) to hold Department objects.
    • The Department objects (math_dept, cs_dept) are created independently of the University object.
    • The University object maintains a relationship with these Department objects, but it doesn't exclusively own them.
    • The Department objects can exist and be associated with other University objects or can continue to exist even if the my_university object is destroyed. Their lifecycle is independent.

Diagram (Conceptual):

Composition:

+----------+      1     1     +-------+
| Computer |------>o------|  CPU  |
+----------+              +-------+
| +brand   |              | +model |
| +cpu     |              | +process_data()|
| +run()    |              +-------+
+----------+
(Solid diamond indicates strong composition relationship - CPU is part of and dies with the Computer)

Aggregation:

+------------+      1..* +------------+
| University |------>o--------| Department |
+------------+                +------------+
| +name      |                | +name      |
| +departments|                | +list_courses()|
| +add_department()|        +------------+
| +list_all_departments()|
+------------+
(Hollow diamond indicates weak aggregation relationship - University has Departments, but Departments can exist independently)

Links to External Resources: