# Code smells

## Bloaters

Smells where methods, classes and parameter lists grow too large to read, test or change safely, usually one small addition at a time.

- [Long Method](https://aipatterns.dev/refactoring/smells/long-method.md): A function that does several jobs in a row and has grown too long to read, name or test as one unit.
- [Large Class](https://aipatterns.dev/refactoring/smells/large-class.md): A class with too many fields, methods or responsibilities, so every change risks breaking something unrelated inside it.
- [Primitive Obsession](https://aipatterns.dev/refactoring/smells/primitive-obsession.md): Domain concepts like money, emails, IDs or statuses are passed around as raw strings and numbers, so their rules get re-checked everywhere.
- [Long Parameter List](https://aipatterns.dev/refactoring/smells/long-parameter-list.md): A function takes so many parameters that callers mix up their order and every new option changes every call site.
- [Data Clumps](https://aipatterns.dev/refactoring/smells/data-clumps.md): The same group of variables travels together through fields and parameters, signaling a missing object that should own them.

## Object-Orientation Abusers

Smells where object-oriented features are missing or misapplied, such as type switches, half-used fields and inheritance that does not fit.

- [Switch Statements](https://aipatterns.dev/refactoring/smells/switch-statements.md): The same switch or if-chain over a type code is repeated across the codebase, so adding one case means editing every copy.
- [Temporary Field](https://aipatterns.dev/refactoring/smells/temporary-field.md): A field that is set and meaningful only during one operation or in one special case, and is empty or stale the rest of the time.
- [Refused Bequest](https://aipatterns.dev/refactoring/smells/refused-bequest.md): A subclass inherits methods or data it does not want, overriding them to throw or do nothing, so the hierarchy lies about what it can do.
- [Alternative Classes with Different Interfaces](https://aipatterns.dev/refactoring/smells/alternative-classes-with-different-interfaces.md): Two classes do the same job but expose different method names or signatures, so callers cannot swap one for the other.

## Change Preventers

Smells where one change forces edits in many places, or one class changes for many unrelated reasons, making every edit slow and risky.

- [Divergent Change](https://aipatterns.dev/refactoring/smells/divergent-change.md): One class gets edited for many unrelated reasons, so every kind of change lands in the same file and collides with every other kind.
- [Shotgun Surgery](https://aipatterns.dev/refactoring/smells/shotgun-surgery.md): One logical change forces small edits in many classes, so one missed edit ships an inconsistent system.
- [Parallel Inheritance Hierarchies](https://aipatterns.dev/refactoring/smells/parallel-inheritance-hierarchies.md): Every new subclass in one hierarchy forces a matching subclass in another, so two trees must always grow in lockstep.

## Dispensables

Smells where code, comments or abstractions add nothing, and removing them makes the program shorter and clearer with no loss of behavior.

- [Comments](https://aipatterns.dev/refactoring/smells/comments.md): Comments that explain what unclear code does are a sign the code should be renamed or restructured so it explains itself.
- [Duplicate Code](https://aipatterns.dev/refactoring/smells/duplicate-code.md): The same logic appears in two or more places, so every fix and change must be made several times and the copies drift apart.
- [Lazy Class](https://aipatterns.dev/refactoring/smells/lazy-class.md): A class does too little to justify the file, name and indirection it costs; fold it into its caller or delete it.
- [Data Class](https://aipatterns.dev/refactoring/smells/data-class.md): A class holds fields and accessors but no behavior, while other classes reach in to do the work that belongs to it.
- [Dead Code](https://aipatterns.dev/refactoring/smells/dead-code.md): Variables, parameters, branches, methods or classes that nothing uses still sit in the codebase, costing reading time and misleading readers.
- [Speculative Generality](https://aipatterns.dev/refactoring/smells/speculative-generality.md): Abstractions, hooks and parameters built for future needs that never arrived make code harder to read without serving any current use.

## Couplers

Smells where classes depend too much on each other's data or structure, or where delegation is overused, so one change ripples through others.

- [Feature Envy](https://aipatterns.dev/refactoring/smells/feature-envy.md): A method reads and computes on another object's data more than its own. Move the logic to where the data lives.
- [Inappropriate Intimacy](https://aipatterns.dev/refactoring/smells/inappropriate-intimacy.md): Two classes reach into each other's private fields and internals. Cut the back-and-forth by moving members or narrowing what each exposes.
- [Message Chains](https://aipatterns.dev/refactoring/smells/message-chains.md): Client code walks a chain like a.getB().getC().getD() to reach what it needs, coupling itself to every link in the path.
- [Middle Man](https://aipatterns.dev/refactoring/smells/middle-man.md): A class mostly forwards calls to another object and adds nothing. Let clients talk to the real object or fold the wrapper away.

## Other Smells

Smells that do not fit the main groups, currently the gap left when a library class you cannot edit lacks an operation you need.

- [Incomplete Library Class](https://aipatterns.dev/refactoring/smells/incomplete-library-class.md): A library type lacks a method you need and you cannot edit it, so helper logic for it is scattered across your code.
- [Thin Tool Wrapper](https://aipatterns.dev/refactoring/smells/thin-tool-wrapper.md): A tool for an agent or API consumer that passes an upstream operation through raw - one endpoint, one tool, provider-shaped payloads - so every real task becomes a chain of calls over low-signal data.
