Composition
A whole that owns its parts: it creates them, nothing else holds them, and they end when it ends. Also the design habit of building behavior by combining objects instead of inheriting.
Overview
Composition is the strongest whole-part relationship. The whole creates its parts, keeps them private, and the parts have no life of their own. A house has rooms; when the house is demolished the rooms are gone. An order has line items; delete the order and the line items go with it. In UML this is a filled diamond at the whole.
The word is also used for a second, related idea: building an object's behavior by giving it other objects to delegate to, instead of inheriting from a base class. That is the 'composition' in 'favor object composition over class inheritance', a guideline from the Design Patterns book (Gamma, Helm, Johnson and Vlissides, 1994). Interviewers ask about both meanings, often in the same conversation, so this topic covers both and says which is which.
The whole owns the part
- Who creates the part? — The whole, usually in its constructor
- Who else holds the part? — Nobody; it is a private detail of the whole
- How many wholes can a part be in? — At most one at a time (UML 2.5.1)
- The whole is deleted — Its parts are deleted with it (UML 2.5.1)
- UML mark — Filled diamond at the whole
The UML standard states the rule directly: a composite part may be included in at most one composite object at a time, and if the composite is deleted, its parts are deleted with it. It also allows a part to be removed from the whole before the whole is deleted, in which case the part survives. That detail is worth saying in an interview: composition is about who is responsible for the part, not a promise that the part can never move.
Lifecycle in code
In code, composition means the whole calls the part's constructor and stores the result in a private field. Because no one outside holds the part, it becomes unreachable as soon as the whole does. In CPython that usually means it is freed right away; the language reference says CPython's reference counting collects most objects as soon as they become unreachable, but tells you not to depend on the exact timing. A weak reference lets the example observe that without keeping the part alive.
Composition over inheritance
The second meaning is a design choice. When you want a class to have some behavior, you can inherit it from a base class or you can hold an object that provides it and delegate. The Design Patterns book recommends delegation as the default because it keeps the classes loosely coupled: the wrapper depends only on the part's public interface, and the part can be swapped at runtime.
- Coupling — Subclass sees and depends on the parent's internals — Wrapper uses only the part's public interface
- Change at runtime — Fixed when the class is written — Swap the part any time
- Combining behaviors — One parent chain; mixing several is awkward — Hold several parts
- Surface area — Inherits every public method, wanted or not — Exposes only what you write
- Testing — Hard to isolate from the parent — Pass a fake part
Ownership in different languages
How a language expresses 'this object owns that one' differs, and interviewers who ask about C++ or Java expect you to know the idiom.
- Python — Create the part in init, store it in a private field, do not return it — The part is unreachable once the whole is; CPython frees it when no references remain
- Java — private final Part part = new Part(); and no getter — Same reachability rule; the garbage collector frees the part when the whole is gone
- C++ — A member object, or std::unique_ptr — A member dies with the object; unique_ptr owns its object, cannot be copied, and deletes it when the pointer goes out of scope
Composition in a database
A composed part is a row that cannot exist without its whole. Model it with a NOT NULL foreign key and ON DELETE CASCADE. PostgreSQL's documentation recommends CASCADE for exactly this case, where the referencing row is a component that cannot exist independently.
- 0
What you will be able to do
- Tell the two meanings of composition apart and answer each on its own terms.
- Implement ownership in code: private creation, no sharing, part dies with the whole.
- Refactor an inheritance chain into delegation and explain what improved.
- State the UML rule for composite aggregation from the standard.
- Carry the decision into a schema with the right foreign key and delete rule.
Interview questions
- Why is composition preferred over inheritance?
- How do you implement composition, and how does that differ from aggregation in code?
- If I inject the part through the constructor, is it still composition?
- What is the fragile base class problem, and how does composition avoid it?
- How does composition show up in UML and in a database schema?
Sign up free to read the full topic
More Low-Level Design topics
Start free on Cariara · Coding problems · System design studio