Aggregation
Weak ownership - parts can exist without the whole.
Aggregation is a “has-a” relationship where one class contains another, but the contained class can exist independently. It represents a weak ownership relationship.
What is Aggregation?
Section titled “What is Aggregation?”Aggregation represents:
- “Has-a” relationship (weak ownership)
- Parts can exist independently of the whole
- Parts can belong to multiple wholes
- Lifecycle independence - parts aren’t destroyed when whole is destroyed
Key Characteristics
Section titled “Key Characteristics”- Weak ownership - Container doesn’t own the parts
- Independent lifecycle - Parts can exist without container
- Multi-ownership - Parts can belong to multiple containers
- Hollow diamond in UML diagrams
Basic Aggregation Example
Section titled “Basic Aggregation Example”class University: def __init__(self, name: str): self.name = name self.students = [] # Aggregation - students can exist without university
def add_student(self, student): self.students.append(student)
class Student: def __init__(self, name: str, student_id: str): self.name = name self.student_id = student_id # Student can exist without being in a university
# Students can exist independentlystudent1 = Student("Alice", "S001")student2 = Student("Bob", "S002")
university = University("MIT")university.add_student(student1)university.add_student(student2)
# Students still exist even if university is deleteddel university# student1 and student2 still existpublic class University { private String name; private java.util.List<Student> students; // Aggregation - students can exist without university
public University(String name) { this.name = name; this.students = new java.util.ArrayList<>(); }
public void addStudent(Student student) { students.add(student); }}
public class Student { private String name; private String studentId;
// Student can exist without being in a university public Student(String name, String studentId) { this.name = name; this.studentId = studentId; }}
// Usagepublic class Main { public static void main(String[] args) { // Students can exist independently Student student1 = new Student("Alice", "S001"); Student student2 = new Student("Bob", "S002");
University university = new University("MIT"); university.addStudent(student1); university.addStudent(student2);
// Students still exist even if university reference is null university = null; // student1 and student2 still exist }}Visual Representation
Section titled “Visual Representation”Real-World Example: Shopping Cart
Section titled “Real-World Example: Shopping Cart”class Product: def __init__(self, sku: str, name: str, price: float): self.sku = sku self.name = name self.price = price
class ShoppingCart: def __init__(self, customer_name: str): self.customer_name = customer_name self.items = [] # Aggregation - products exist independently
def add_item(self, product, quantity: int = 1): self.items.append({"product": product, "quantity": quantity})
def get_total(self): return sum(item["product"].price * item["quantity"] for item in self.items)
# Products exist independentlylaptop = Product("LAP-001", "Laptop", 999.99)mouse = Product("MOU-001", "Mouse", 29.99)
# Multiple carts can reference same productscart1 = ShoppingCart("Alice")cart2 = ShoppingCart("Bob")
cart1.add_item(laptop, 1)cart1.add_item(mouse, 2)
cart2.add_item(laptop, 1) # Same product in different cart
print(f"Cart 1 total: ${cart1.get_total():.2f}") # $1059.97print(f"Cart 2 total: ${cart2.get_total():.2f}") # $999.99public class Product { private String sku; private String name; private double price;
public Product(String sku, String name, double price) { this.sku = sku; this.name = name; this.price = price; }
public double getPrice() { return price; }}
public class CartItem { private Product product; private int quantity;
public CartItem(Product product, int quantity) { this.product = product; this.quantity = quantity; }
public double getSubtotal() { return product.getPrice() * quantity; }}
public class ShoppingCart { private String customerName; private java.util.List<CartItem> items; // Aggregation - products exist independently
public ShoppingCart(String customerName) { this.customerName = customerName; this.items = new java.util.ArrayList<>(); }
public void addItem(Product product, int quantity) { items.add(new CartItem(product, quantity)); }
public double getTotal() { return items.stream() .mapToDouble(CartItem::getSubtotal) .sum(); }}
// Usagepublic class Main { public static void main(String[] args) { // Products exist independently Product laptop = new Product("LAP-001", "Laptop", 999.99); Product mouse = new Product("MOU-001", "Mouse", 29.99);
// Multiple carts can reference same products ShoppingCart cart1 = new ShoppingCart("Alice"); ShoppingCart cart2 = new ShoppingCart("Bob");
cart1.addItem(laptop, 1); cart1.addItem(mouse, 2);
cart2.addItem(laptop, 1); // Same product in different cart
System.out.printf("Cart 1 total: $%.2f%n", cart1.getTotal()); // $1059.97 System.out.printf("Cart 2 total: $%.2f%n", cart2.getTotal()); // $999.99 }}Aggregation vs Composition
Section titled “Aggregation vs Composition”| Feature | Aggregation | Composition |
|---|---|---|
| Ownership | Weak | Strong |
| Lifecycle | Independent | Dependent |
| Multi-ownership | Yes | No |
| UML Symbol | Hollow diamond | Filled diamond |
| Example | University → Students | Car → Engine |
Key Takeaways
Section titled “Key Takeaways”When to Use Aggregation
Section titled “When to Use Aggregation”Use Aggregation when:
- Parts can exist without the whole
- Parts can belong to multiple wholes
- You need flexibility in relationships
- Parts have independent lifecycle
- Relationship is “part-of” but not essential
Examples:
- University → Students (students can transfer)
- Shopping Cart → Products (products exist independently)
- Team → Players (players can change teams)
- Library → Books (books can be removed)
- Department → Employees (employees can move departments)