Object-Oriented Design – Is This Aggregation or Composition?

cobject-oriented

As far as my understanding for composition, the children cannot exist without the parent. But my instructor is suggesting that the following example is an aggregation, I just want another opinion.

class ItemForKids { }
class ItemForMen { }
class ItemForWomen { }
class PageContent {
    private:
        ItemForKids* itemForKids = NULL;
        ItemForMen* itemForMen = NULL;
        ItemForWomen* itemForWomen = NULL;
    public:
        PageContent() {
            this->itemForKids = new ItemForKids();
            this->itemForMen = new ItemForMen();
            this->itemForWomen = new ItemForWomen();
        }
        ~PageContent() {
            delete this->itemForKids;
            delete this->itemForMen;
            delete this->itemForWomen;
        }
}

2 Questions:

  1. Is above example aggregation or is it composition?
  2. My instructor suggests that if we change the pointers to regular variable then we don't need to initialize the object in constructor and then it will become composition, is this true?

Best Answer

The aggregation vs. composition distinction is not terribly relevant in practice. In C++, it is better to talk about ownership: who owns a particular object and is responsible for destroying it?

The majority of C++ objects are used by value and are therefore destroyed automatically. This code is equivalent to the code you posted in the question:

class ItemForKids { };
class ItemForMen { };
class ItemForWomen { };
class PageContent {
    private:
        ItemForKids itemForKids;
        ItemForMen itemForMen;
        ItemForWomen itemForWomen;
    public:
        // PageContent() default constructor
        // ~PageContent() default destructor
};

Modern C++ code tries to do as much as possible by value because automatic destruction makes life so much easier (and eradicates a common source of errors). If using a value is not possible directly, we use smart pointers like std::unique_ptr that destroy the pointed-to object when they are destroyed.

In your question the PageContent class is responsible for deleting its itemForX members, so this can be characterized as “aggregation”. Your instructor is therefore mostly correct in this case. This is a simple case because the class both constructs and deletes its members. If ownership of the members is transferred into the class, e.g.

ProductPage(ItemForKids* itemForKids) {
  this->itemForKids = itemForKids;
}

then this is a more borderline case. I'd argue that this would still be best described as aggregation because there's still ownership (the responsibility to delete), but I do see that it could be argued differently.

So in the end, do what your instructor expects you to do, and forget about “aggregation” after the course. It is not useful for most programming, especially compared to concepts like ownership.

Note that aggregation has a related but distinct meaning in (relational) database systems.