Number of Overridden Methods (NOOM)
Number of overridden methods is a quantitative metric that measures the number of methods a class/mixin/enum overrides from its superclass or interface. This metric provides insight into how much a class customizes or modifies inherited behavior.
High NOOM values can indicate that a class diverges significantly from its superclass, potentially suggesting that composition or interface implementation may be a better design choice than inheritance.
Why Be Cautious
High number of overridden methods can lead to:
- Increased Complexity: Overriding too many methods makes it harder to understand the purpose and behavior of the subclass.
- Maintenance Challenges: Changes in the superclass may require updates in all overridden methods, increasing maintenance.
- Potential Misuse of Inheritance: High NOOM might suggest that the subclass is overly dependent on the superclass, potentially benefiting more from a different design pattern like composition.
How Can You Improve High Number of Overridden Methods?
If a class overrides numerous methods, consider using composition instead. Composition allows classes to reuse behavior without tightly coupling to a specific superclass.
If the primary purpose of overriding methods is to fulfill a contract, consider implementing an interface instead of inheriting from a class. This can reduce unnecessary inheritance and keep dependencies flexible.
High NOOM may indicate that the class has taken on too many responsibilities from the superclass. Breaking the class down to focus on a single responsibility can reduce the need to override multiple methods.
Config Example
dcm:
metrics:
number-of-overridden-methods:
threshold: 10
To set multiple threshold or other common config options, refer to the Configuring Metrics page.
Example
To view what contributes to the metric value, generate an HTML report.
❌ Bad: High Number of Overridden Methods
class Vehicle {
void start() => print("Vehicle starting");
void stop() => print("Vehicle stopping");
void fuelUp() => print("Vehicle fueling up");
void honk() => print("Vehicle honking");
}
// NOOM: 5
class AdvancedVehicle extends Vehicle {
void start() => print("AdvancedVehicle starting with self-check");
void stop() => print("AdvancedVehicle stopping with diagnostics");
void fuelUp() => print("AdvancedVehicle fueling up with premium");
void honk() => print("AdvancedVehicle honking with custom sound");
void adjustMirrors() => print("AdvancedVehicle adjusting mirrors");
void enableAutoPilot() => print("Autopilot enabled");
}
✅ Good: Low Number of Overridden Methods
class Vehicle {
void start() => print("Vehicle starting");
void stop() => print("Vehicle stopping");
void fuelUp() => print("Vehicle fueling up");
void honk() => print("Vehicle honking");
}
class PremiumVehicleFeatures {
void fuelUp() => print("Vehicle fueling up with premium");
void enableAutoPilot() => print("Autopilot enabled");
void adjustMirrors() => print("Adjusting mirrors automatically");
}
// NOOM: 2
class AdvancedVehicle extends Vehicle {
final PremiumVehicleFeatures premiumFeatures;
AdvancedVehicle(this.premiumFeatures);
void start() => print("AdvancedVehicle starting with self-check");
void honk() => print("AdvancedVehicle honking with custom sound");
void fuelPremium() => premiumFeatures.fuelUp();
void activateAutoPilot() => premiumFeatures.enableAutoPilot();
}