- Home
- Skills
- Yanko Belov
- Code Craft
- Composition Over Inheritance
composition-over-inheritance_skill
- TypeScript
6
GitHub Stars
1
Bundled Files
2 months ago
Catalog Refreshed
4 months ago
First Indexed
Readme & install
Copy the install command, review bundled files from the catalogue, and read any extended description pulled from the listing source.
Installation
Preview and clipboard use veilstrat where the catalogue uses aiagentskills.
npx veilstrat add skill yanko-belov/code-craft --skill composition-over-inheritance- SKILL.md5.5 KB
Overview
This skill recommends favoring composition over class inheritance when designing TypeScript classes. It explains why inheritance creates tight coupling and rigid hierarchies and shows how to build flexible, testable components by composing behaviors via interfaces and injected implementations. The guidance emphasizes defaulting to composition and reserving inheritance for rare, true type hierarchies or framework-imposed cases.
How this skill works
The skill inspects design decisions where classes extend other classes, looking for inheritance smells like deep hierarchies, overridden parent methods, or duplicated behavior. It guides you to extract capabilities as interfaces and reusable behavior objects, then compose those behaviors into concrete classes. It also provides patterns, detection heuristics, and short responses to common rationalizations for using inheritance.
When to use it
- Designing relationships between classes and weighing extends vs. implements
- When a class needs behavior from multiple sources or multiple parents
- When you find class hierarchies deeper than two levels
- When a subclass overrides many parent methods or inherits unused methods
- When changes in a parent class cascade and break children
Best practices
- Default to composition: model capabilities as interfaces and inject behaviors
- Keep inheritance shallow (max two levels) and only for true type hierarchies
- Extract shared methods into composable behavior objects instead of extending
- Prefer loose coupling so behaviors can be mocked and swapped at runtime
- Watch for the diamond problem and replace multiple inheritance attempts with composition
Example use cases
- Modeling animals where one entity needs flying and swimming without duplicating code
- Refactoring a deep class hierarchy that becomes fragile after parent changes
- Implementing reusable capabilities (e.g., logging, persistence, validation) across unrelated classes
- Replacing extends-based code reuse with interfaces and injected behavior objects
- When frameworks force inheritance reluctantly, keep classes small and behavior composable
FAQ
Use inheritance only for true type hierarchies, framework requirements, or extending library classes you don't control, and keep hierarchies shallow.
How do I get polymorphism without inheritance?
Define interfaces for the required behavior and have classes implement them; you can treat instances uniformly through interface types.