agentleFS
ROCmROCm/rocprofiler-systems-skills/skills/code-smells/SKILL.md

code-smells

Skill5 starsChanged 16 days agoMITView on GitHub

Detect code smells based on refactoring.guru catalog - use when analyzing code for anti-patterns and refactoring opportunities

4 other projects use a version of this.

Adopted by

Most recently taken up by

The file

We split this skill into the rules it gives an agent

9 rules. 0 are common, 9 are distinctive, and 0 are very specific to this project.

  • 0

    Common

    Most of the 3 edited versions we read keep these.

  • 9

    Distinctive

    This author's own choices. Worth a look.

  • 0

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    When detecting smells, report findings in structured format with:

    line 16
  2. Distinctive:

    When reporting code smells, use this structured format:

    line 43
  3. Distinctive:

    No type safety (passing wrong int to function)

    line 134
  4. Distinctive:

    No place to add validation or behavior

    line 136
  5. Distinctive:

    No single place for operations on the data

    line 201
  6. Distinctive:

    When to ignore: If deduplication makes code uglier, keep the parallel structure.

    line 425
  7. Distinctive:

    Every class costs maintenance

    line 506
  8. Distinctive:

    No behavior, just data container

    line 531
  9. Distinctive:

    No substantial independent behavior

    line 716

“Common” is measured: kept by at least 6 in 10 of the 3 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Code Smells Detection

Comprehensive catalog of code smells for detecting anti-patterns and identifying refactoring opportunities. Based on the Refactoring.Guru Code Smells Catalog.

<IMPORTANT> This skill is a **reference catalog** for code smell detection. It is used by: - `pr-review` Agent 3 (Code Smells Agent) during PR review - `planning-refactor` when identifying improvement opportunities - Standalone code quality analysis

When detecting smells, report findings in structured format with:

  • File:Line location
  • Smell name and category
  • Severity score
  • Suggested refactoring</IMPORTANT>

When to Use

ContextTrigger
PR ReviewInvoked by pr-review Code Smells Agent
Refactoring PlanningBefore planning-refactor to identify targets
Code Quality AuditUser asks to analyze code quality or find anti-patterns
Technical Debt AssessmentIdentifying areas needing improvement

Severity Levels

SeverityScoreImpactExamples
Critical100Causes bugs, crashes, security issuesFeature Envy causing null dereference
Must Fix80Significantly harms maintainabilityGod Class, Shotgun Surgery
Should Fix50Reduces code qualityLong Method, Duplicate Code
Nitpick20Minor improvement opportunityLazy Class, Comments

Output Format

When reporting code smells, use this structured format:

| File:Line | Smell | Category | Severity | Suggested Refactoring |
|-----------|-------|----------|----------|----------------------|
| handler.cpp:120-195 | Long Method (75 lines) | Bloater | Should Fix (50) | Extract Method: split into validateRequest(), processData(), buildResponse() |
| config.cpp:45 | Magic Number | Bloater | Should Fix (50) | Replace Magic Number: `const int MAX_RETRIES = 42;` |

Category 1: Bloaters

Code that has grown to excessive proportions, making it hard to work with.

Long Method

Threshold: >10 lines warrants questions, >50 lines is definite smell

Signs:

  • Method contains too many lines of code
  • You need to scroll to see the whole method
  • Method does multiple things

Why it's bad:

  • Hard to understand and maintain
  • Hides duplicate code
  • Makes testing difficult
  • Long methods accumulate like "Hotel California" - easy to add, hard to remove

Detection criteria:

- Lines > 50: Should Fix (50)
- Lines > 100: Must Fix (80)
- Method does more than one thing (multiple responsibilities)
- Requires extensive comments to explain

Refactoring:

TechniqueWhen to Use
Extract MethodSplit into smaller methods with descriptive names
Replace Temp with QueryLocal variables interfering with extraction
Introduce Parameter ObjectMany parameters passed between methods
Decompose ConditionalComplex if/else chains
Replace Method with Method ObjectWhen extraction is too complex

Large Class

Threshold: Too many fields, methods, or lines (>500 lines warrants review)

Signs:

  • Class contains excessive fields/methods/lines
  • Class has multiple unrelated responsibilities
  • You struggle to summarize what the class does in one sentence

Why it's bad:

  • Cognitive overload (too many attributes to track)
  • Code duplication within the class
  • Violates Single Responsibility Principle

Detection criteria:

- Lines > 500: Should Fix (50)
- Lines > 1000: Must Fix (80)
- >10 public methods: Review for SRP violation
- >15 fields: Likely doing too much
- Multiple unrelated method groups

Refactoring:

TechniqueWhen to Use
Extract ClassSeparate distinct behavioral components
Extract SubclassBehavior used only in some cases
Extract InterfaceDefine contract for operations
Duplicate Observed DataGUI classes with domain logic

Primitive Obsession

Signs:

  • Using primitives instead of small objects (money, phone numbers, ranges)
  • Constants encoding information (USER_ADMIN_ROLE = 1)
  • String constants as field names in arrays
  • Using int for IDs instead of typed wrapper

Why it's bad:

  • No type safety (passing wrong int to function)
  • Related operations scattered across codebase
  • No place to add validation or behavior
  • Duplicate code for handling the primitive

Detection criteria:

- Multiple functions operating on same primitive group: Should Fix (50)
- Constants simulating types: Should Fix (50)
- No domain objects for business concepts (money, date ranges, coordinates): Should Fix (50)

Refactoring:

TechniqueWhen to Use
Replace Data Value with ObjectGroup primitives into dedicated classes
Introduce Parameter ObjectPrimitives in method parameters
Preserve Whole ObjectPassing extracted values instead of object
Replace Type Code with Class/Subclasses/StateConstants simulating types
Replace Array with ObjectUsing arrays with string keys

Long Parameter List

Threshold: >3-4 parameters

Signs:

  • Method has more than 3-4 parameters
  • Parameters are passed through multiple method calls
  • Hard to remember parameter order
  • Boolean parameters for mode switching

Why it's bad:

  • Difficult to understand method signature
  • Easy to pass wrong arguments
  • Often indicates the method is doing too much
  • Creates tight coupling

Detection criteria:

- 4-5 parameters: Should Fix (50)
- 6+ parameters: Must Fix (80)
- Boolean "flag" parameters: Should Fix (50)
- Parameters from same object: Should Fix (50)

Refactoring:

TechniqueWhen to Use
Replace Parameter with Method CallParameter is result of another call
Preserve Whole ObjectPassing multiple fields from same object
Introduce Parameter ObjectGroup related parameters

When to ignore: Creating dependencies between classes may be worse than long parameter list.


Data Clumps

Signs:

  • Same group of variables appears in multiple places
  • Parameters that always travel together
  • Removing one variable makes others meaningless

Why it's bad:

  • Code duplication
  • No single place for operations on the data
  • Easy to pass incomplete groups

Detection criteria:

- Same 3+ parameters in multiple method signatures: Should Fix (50)
- Same fields grouped in multiple classes: Should Fix (50)
- Database connection parameters passed separately: Should Fix (50)

Refactoring:

TechniqueWhen to Use
Extract ClassFor class fields
Introduce Parameter ObjectFor method parameters
Preserve Whole ObjectPass object instead of extracting values

Category 2: Object-Orientation Abusers

Incomplete or incorrect application of object-oriented programming principles.

Switch Statements

Signs:

  • Complex switch operator or if-else chain based on type
  • Same switch logic scattered across multiple methods
  • Adding a new case requires changes in many places

Why it's bad:

  • Violates Open/Closed Principle
  • Duplicate switch logic across codebase
  • Easy to forget updating all switches
  • Rare use of switch is hallmark of good OOP

Detection criteria:

- Switch on type/enum with behavior: Should Fix (50)
- Same switch in multiple places: Must Fix (80)
- Switch with >5 cases with different behavior: Should Fix (50)

Refactoring:

TechniqueWhen to Use
Replace Conditional with PolymorphismWhen switch determines behavior
Replace Type Code with SubclassesType codes with distinct behavior
Replace Type Code with State/StrategyBehavior varies at runtime
Replace Parameter with Explicit MethodsSimple value-based switches
Introduce Null ObjectNull checks in conditionals

When to ignore: Factory patterns legitimately use switch to create objects.


Temporary Field

Signs:

  • Fields only used in certain circumstances
  • Fields remain empty/null most of the time
  • Field existence confuses readers

Why it's bad:

  • Developers expect fields to always be meaningful
  • Requires null checks scattered through code
  • Hides actual dependencies

Detection criteria:

- Field used in <25% of methods: Should Fix (50)
- Field only set in one method and used in another: Should Fix (50)
- Fields for algorithm-specific data: Should Fix (50)

Refactoring:

TechniqueWhen to Use
Extract ClassMove field and related code to separate class
Replace Method with Method ObjectAlgorithm needs many temp fields
Introduce Null ObjectReplace null checks with null object pattern

Refused Bequest

Signs:

  • Subclass uses only some parent methods/properties
  • Inherited methods throw exceptions or do nothing
  • Subclass doesn't follow Liskov Substitution Principle

Why it's bad:

  • Confusing hierarchy (Dog inherits from Chair?)
  • Breaking substitutability
  • Indicates wrong abstraction

Detection criteria:

- Override methods with empty body or exception: Should Fix (50)
- Subclass ignores >50% of parent interface: Should Fix (50)
- Inheritance for code reuse, not "is-a": Should Fix (50)

Refactoring:

TechniqueWhen to Use
Replace Inheritance with DelegationWrong hierarchy, use composition
Extract SuperclassCreate proper abstraction for shared behavior

Alternative Classes with Different Interfaces

Signs:

  • Two classes do the same thing with different method names
  • Parallel implementations that could be unified
  • Duplicate functionality discovered during review

Why it's bad:

  • Code duplication across classes
  • Confusion about which class to use
  • Maintenance burden

Detection criteria:

- Classes with same purpose, different interface: Should Fix (50)
- Duplicate logic in differently-named methods: Should Fix (50)

Refactoring:

TechniqueWhen to Use
Rename MethodAlign method names to common interface
Move MethodConsolidate implementations
Extract SuperclassShare common behavior
Delete redundant classAfter consolidation

When to ignore: Classes in different libraries with independent versioning.


Category 3: Change Preventers

Issues that require changes in multiple places when a single change is needed.

Divergent Change

Signs:

  • Single class needs changes for multiple unrelated reasons
  • Adding new feature requires changing many methods in one class
  • Class has multiple "areas" of responsibility

Why it's bad:

  • Single class handles too many concerns
  • Any change risks breaking unrelated functionality
  • Violates Single Responsibility Principle

Detection criteria:

- Class changes for >2 unrelated reasons: Should Fix (50)
- Class has distinct "sections" of functionality: Should Fix (50)
- Methods naturally group into separate concerns: Should Fix (50)

Refactoring:

TechniqueWhen to Use
Extract ClassSeparate each concern into its own class
Extract Superclass/SubclassWhen classes share some behavior

Shotgun Surgery

Signs:

  • Single change requires edits to many different classes
  • Adding a feature means touching 5+ files
  • Opposite of Divergent Change

Why it's bad:

  • Easy to miss a required change
  • High chance of introducing bugs
  • Expensive maintenance

Detection criteria:

- Feature addition touches 5+ classes: Must Fix (80)
- Single responsibility scattered across classes: Must Fix (80)
- "Overzealous" previous separation causing this: Must Fix (80)

Refactoring:

TechniqueWhen to Use
Move Method/FieldConsolidate scattered responsibility
Inline ClassAfter consolidation, remove empty shells

Parallel Inheritance Hierarchies

Signs:

  • Creating subclass in one hierarchy requires subclass in another
  • Class prefixes match across hierarchies
  • Mirrored class structures

Why it's bad:

  • Duplicate maintenance
  • Growing complexity as hierarchies expand
  • Easy to forget creating matching class

Detection criteria:

- Two hierarchies with matching structures: Should Fix (50)
- Adding to one requires adding to another: Should Fix (50)
- Prefixes like "XHandler/XFactory": Should Fix (50)

Refactoring:

TechniqueWhen to Use
Move Method/FieldMake one hierarchy reference the other
Eliminate redundant hierarchyAfter consolidation

When to ignore: If deduplication makes code uglier, keep the parallel structure.


Category 4: Dispensables

Pointless and unneeded elements whose absence would make code cleaner.

Comments

Signs:

  • Method filled with explanatory comments
  • Comments describe WHAT instead of WHY
  • Comments are outdated or incorrect
  • Comments compensate for unclear code

Why it's bad:

  • "The best comment is a good name for a method or class"
  • Comments can become outdated and misleading
  • Indicates code needs refactoring, not explaining

Detection criteria:

- Comment explains what code does (not why): Nitpick (20)
- Commented-out code: Should Fix (50)
- Comment contradicts code: Must Fix (80)
- TODOs without ticket references: Nitpick (20)

Refactoring:

TechniqueWhen to Use
Extract VariableComplex expression needs explanation
Extract MethodUse comment text as method name
Rename MethodMethod name should make comment unnecessary
Introduce AssertionDocument required state

When acceptable: Comments explaining WHY (design decisions, complex algorithms, non-obvious constraints).


Duplicate Code

Signs:

  • Two code fragments look almost identical
  • Same logic in different methods/classes
  • Copy-paste programming

Why it's bad:

  • Changes must be made in multiple places
  • Easy to miss updating all copies
  • Increases maintenance burden

Detection criteria:

- Identical code blocks: Should Fix (50)
- Similar code blocks (>80% same): Should Fix (50)
- Copy-paste with minor modifications: Should Fix (50)
- Same algorithm implemented differently: Should Fix (50)

Refactoring:

TechniqueWhen to Use
Extract MethodWithin single class
Pull Up MethodIn sibling subclasses
Form Template MethodSimilar but not identical algorithms
Extract SuperclassAcross unrelated classes
Extract ClassWhen hierarchy inappropriate
Consolidate Conditional ExpressionDuplicate conditions

Lazy Class

Signs:

  • Class doesn't do enough to justify existence
  • Class was reduced by refactoring and is now minimal
  • Class created for anticipated features that never came

Why it's bad:

  • Every class costs maintenance
  • Adds complexity without value
  • Cognitive overhead for developers

Detection criteria:

- Class with <3 methods: Nitpick (20)
- Class that just delegates to another: Nitpick (20)
- Subclass with minimal additions: Nitpick (20)

Refactoring:

TechniqueWhen to Use
Inline ClassMerge into another class
Collapse HierarchyMerge minimal subclass with parent

When to ignore: Class represents future expansion point.


Data Class

Signs:

  • Class contains only fields and getters/setters
  • No behavior, just data container
  • Other classes operate on its data

Why it's bad:

  • Violates encapsulation
  • Logic operating on data is scattered
  • Can't enforce invariants

Detection criteria:

- Class with only fields + accessors: Should Fix (50)
- No methods operating on own data: Should Fix (50)
- Other classes doing Feature Envy on this class: Should Fix (50)

Refactoring:

TechniqueWhen to Use
Encapsulate FieldMake fields private
Encapsulate CollectionFor collections
Move MethodBring behavior from clients into class
Remove Setting MethodAfter class gains behavior
Hide MethodFor overly permissive accessors

Dead Code

Signs:

  • Variable, parameter, field, method, or class no longer used
  • Code after return/throw/break
  • Conditional branches that never execute

Why it's bad:

  • Clutters codebase
  • Confuses developers
  • May be accidentally activated

Detection criteria:

- Unused variable: Nitpick (20)
- Unused method/function: Should Fix (50)
- Unreachable code: Should Fix (50)
- Commented-out code: Should Fix (50)
- Unused class: Should Fix (50)

Refactoring:

TechniqueWhen to Use
DeleteRemove unused code
Remove ParameterUnused parameters
Inline Class/Collapse HierarchyUnused classes

Speculative Generality

Signs:

  • Unused class, method, field, or parameter
  • Hooks for future features that never came
  • Overly abstract code for simple requirements

Why it's bad:

  • "Just in case" code adds complexity
  • YAGNI - You Aren't Gonna Need It
  • Makes code harder to understand

Detection criteria:

- Unused abstraction: Nitpick (20)
- Parameter only used in tests: Nitpick (20)
- Abstract class with single implementation: Nitpick (20)
- Methods that only delegate: Nitpick (20)

Refactoring:

TechniqueWhen to Use
Collapse HierarchyUnnecessary abstract classes
Inline ClassUnnecessary delegation
Inline MethodUnused methods
Remove ParameterUnused parameters

When to ignore: Framework code where users may need the hooks.


Category 5: Couplers

Issues involving excessive coupling between classes or excessive delegation.

Feature Envy

Signs:

  • Method accesses data of another object more than its own
  • Method is more interested in another class
  • Heavy use of another object's getters

Why it's bad:

  • Logic is in wrong place
  • Violates encapsulation
  • Makes refactoring harder

Detection criteria:

- Method uses >3 getters from another object: Should Fix (50)
- Method primarily operates on another class's data: Should Fix (50)
- After data move, operations didn't follow: Should Fix (50)

Refactoring:

TechniqueWhen to Use
Move MethodMove entire method to target class
Extract MethodMove only envious part

When to ignore: Strategy/Visitor patterns intentionally separate behavior from data.


Inappropriate Intimacy

Signs:

  • Class uses internal fields/methods of another class
  • Two classes spend too much time delving into each other
  • Bidirectional dependencies

Why it's bad:

  • Tight coupling
  • Hard to change one class without affecting the other
  • Reduced reusability

Detection criteria:

- Classes accessing each other's private/protected: Must Fix (80)
- Bidirectional association: Should Fix (50)
- Deep knowledge of another class's internals: Should Fix (50)

Refactoring:

TechniqueWhen to Use
Move Method/FieldPut code where data lives
Extract ClassSeparate shared parts
Hide DelegateReduce direct knowledge
Change Bidirectional to UnidirectionalSimplify association
Replace Delegation with InheritanceWhen intimacy is with subclass

Message Chains

Signs:

  • Series of calls like a.b().c().d()
  • Client depends on navigation structure
  • Changes to intermediate classes affect client

Why it's bad:

  • Client coupled to entire chain structure
  • Any chain change requires client updates
  • Violates Law of Demeter

Detection criteria:

- Chain of 3+ method calls: Should Fix (50)
- Chain navigation through multiple objects: Should Fix (50)
- "Train wreck" code: a.getB().getC().getD(): Should Fix (50)

Refactoring:

TechniqueWhen to Use
Hide DelegateShorten chain at each step
Extract Method + Move MethodGet what you need from chain start

Caution: Overly aggressive hiding creates Middle Man smell.


Middle Man

Signs:

  • Class delegates most work to another class
  • Class exists only to forward calls
  • No substantial independent behavior

Why it's bad:

  • Unnecessary indirection
  • Adds complexity without value
  • Often results from over-applying Hide Delegate

Detection criteria:

- Class where >50% methods just delegate: Should Fix (50)
- Class with only pass-through methods: Should Fix (50)
- Gradual functionality migration left empty shell: Should Fix (50)

Refactoring:

TechniqueWhen to Use
Remove Middle ManCall delegate directly

When to ignore:

  • Proxy pattern (intentional delegation)
  • Decorator pattern
  • Hiding dependencies for testing

Incomplete Library Class

Signs:

  • Library doesn't meet your needs
  • Can't modify library code
  • Working around library limitations

Why it's bad:

  • Workarounds scattered across codebase
  • Duplicate solutions to same problem
  • Fragile code depending on library internals

Detection criteria:

- Multiple workarounds for same library limitation: Should Fix (50)
- Helper functions for library functionality: Nitpick (20)

Refactoring:

TechniqueWhen to Use
Introduce Foreign MethodAdd few methods
Introduce Local ExtensionAdd substantial functionality

Quick Reference: Detection Thresholds

SmellThresholdSeverity
Long Method>50 linesShould Fix (50)
Long Method>100 linesMust Fix (80)
Large Class>500 linesShould Fix (50)
Large Class>1000 linesMust Fix (80)
Long Parameter List>4 paramsShould Fix (50)
Long Parameter List>6 paramsMust Fix (80)
Deep Nesting>3 levelsShould Fix (50)
Deep Nesting>5 levelsMust Fix (80)
Magic NumbersAny unexplained literalShould Fix (50)
Duplicate Code>10 lines identicalShould Fix (50)
Feature Envy>3 external gettersShould Fix (50)
Message Chain>3 callsShould Fix (50)
Shotgun Surgery>5 classes touchedMust Fix (80)
God ClassMultiple responsibilitiesMust Fix (80)

Integration with Other Skills

ScenarioNext Skill
Found smells during PR reviewContinue pr-review with findings
Found smells, need refactoringInvoke planning-refactor
Need to understand code firstInvoke exploration-explore-code
Ready to apply specific techniqueInvoke refactoring-techniques for step-by-step guidance
Ready to fix Long MethodUse Extract Method from refactoring-techniques
Ready to fix Feature EnvyUse Move Method from refactoring-techniques

Cross-Reference: This skill identifies WHAT to fix. The refactoring-techniques skill shows HOW to fix it with 60+ techniques and code examples.

References

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.