# 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.

- kind: category
- category: refactoring
- canonical: https://aipatterns.dev/refactoring/smells/couplers
- inspired-by: https://refactoring.guru/refactoring/smells/couplers

## What these smells share

Couplers are about the lines between classes, not the classes themselves. Either behavior sits in the wrong class and keeps reaching for another's data, or callers know too much about how objects are wired together, or a class adds a layer that only forwards.

Too much coupling makes changes spread. Too much indirection makes code hard to follow. These smells pull in both directions, so fixing one can create another.

## Members

- [Feature Envy](https://aipatterns.dev/refactoring/smells/feature-envy.md): a method uses another object's data more than its own.
- [Inappropriate Intimacy](https://aipatterns.dev/refactoring/smells/inappropriate-intimacy.md): two classes reach into each other's private parts.
- [Message Chains](https://aipatterns.dev/refactoring/smells/message-chains.md): clients navigate `a.b().c().d()` to reach what they need.
- [Middle Man](https://aipatterns.dev/refactoring/smells/middle-man.md): a class mostly forwards calls to another and adds nothing.

## How to choose within this category

- One method leaning on one other class is [Feature Envy](https://aipatterns.dev/refactoring/smells/feature-envy.md). Move the method.
- Two classes leaning on each other, in both directions, is [Inappropriate Intimacy](https://aipatterns.dev/refactoring/smells/inappropriate-intimacy.md). Separate the owners.
- A client walking through several objects is [Message Chains](https://aipatterns.dev/refactoring/smells/message-chains.md). Hide the path behind the first object.
- A class that is all forwarding is [Middle Man](https://aipatterns.dev/refactoring/smells/middle-man.md). Remove the layer.
- Message Chains and Middle Man are opposites. [Hide Delegate](https://aipatterns.dev/refactoring/techniques/hide-delegate.md) fixes chains but, overused, creates a middle man; [Remove Middle Man](https://aipatterns.dev/refactoring/techniques/remove-middle-man.md) fixes the middle man but can bring chains back. Aim for the balance where clients depend on a near neighbor and each forwarding method has callers.

## Typical treatments

- [Move Method](https://aipatterns.dev/refactoring/techniques/move-method.md) and [Move Field](https://aipatterns.dev/refactoring/techniques/move-field.md) for envy and intimacy.
- [Extract Class](https://aipatterns.dev/refactoring/techniques/extract-class.md) and [Change Bidirectional Association to Unidirectional](https://aipatterns.dev/refactoring/techniques/change-bidirectional-association-to-unidirectional.md) to untangle two-way dependencies.
- [Hide Delegate](https://aipatterns.dev/refactoring/techniques/hide-delegate.md) for chains.
- [Remove Middle Man](https://aipatterns.dev/refactoring/techniques/remove-middle-man.md) and [Inline Method](https://aipatterns.dev/refactoring/techniques/inline-method.md) for pure forwarders.

## For agents

- Some forwarding is intentional. [Facade](https://aipatterns.dev/design-patterns/facade.md), [Proxy](https://aipatterns.dev/design-patterns/proxy.md), [Adapter](https://aipatterns.dev/design-patterns/adapter.md) and [Decorator](https://aipatterns.dev/design-patterns/decorator.md) are wrappers by design. Do not remove them as middle men.
- Some separation of data and behavior is intentional. [Strategy](https://aipatterns.dev/design-patterns/strategy.md) and [Visitor](https://aipatterns.dev/design-patterns/visitor.md) put logic outside the data on purpose.
- Check for import cycles before and after moving members between modules.
