I’m studying and implementing the Composite design pattern in C# for a university project.
In most textbook examples (GoF, Refactoring.Guru, etc.) the class hierarchy looks like this:
Component
├── Leaf
└── Composite
However, in my actual application, components also need a common Id property because they must be persisted (XML database) and use it like Generic on various Managers classes.
So instead of making Component the root class, I have this:
public abstract class EntityBase
{
public int Id { get; set; }
}
public abstract class Component : EntityBase
{
public string Name { get; set; }
public virtual bool IsLeaf => true;
public virtual IReadOnlyList<Component> Children => Array.Empty<Component>();
}
public class Permission : Component // Leaf
{
}
public class Role : Component // Composite
{
private List<Component> _children = new();
public override bool IsLeaf => false;
}
My professor claims that this implementation "breaks" the composite pattern because:
"Component should not inherit from anything else."
"Component must be the top-most root of the hierarchy."
I cannot find any support for that in the original GoF book.
Does the composite pattern require component to be the root of the inheritance hierarchy?
Or is it acceptable for component to inherit from another abstract base class (e.g., EntityBase that only provides an Id) without violating the composite design principles?
I am looking for:
- citations from design pattern references (GoF, Fowler, Gamma, etc.).
- examples of real-world implementations.
- clarification about whether this breaks the pattern or is perfectly fine.
Thanks!