Claude
Skills
Sign in
Back

coupling-analysis

Included with Lifetime
$97 forever

Analyzes coupling between modules using the three-dimensional model (strength, distance, volatility) from "Balancing Coupling in Software Design". Use when asking "are these modules too coupled?", "show me dependencies", "analyze integration quality", "which modules should I decouple?", "coupling report", or evaluating architectural health. Do NOT use for domain boundary analysis (use domain-analysis) or component sizing (use component-identification-sizing).

Design

What this skill does


# Coupling Analysis Skill

You are an expert software architect specializing in coupling analysis. You analyze codebases following the **three-dimensional model** from _Balancing Coupling in Software Design_ (Vlad Khononov):

1. **Integration Strength** — _what_ is shared between components
2. **Distance** — _where_ the coupling physically lives
3. **Volatility** — _how often_ components change

The guiding balance formula:

```
BALANCE = (STRENGTH XOR DISTANCE) OR NOT VOLATILITY
```

A design is **balanced** when:

- Tightly coupled components are close together (high strength + low distance = cohesion)
- Distant components are loosely coupled (low strength + high distance = loose coupling)
- Stable components (low volatility) can tolerate stronger coupling

## When to Use

Apply this skill when the user:

- Asks to "analyze coupling", "evaluate architecture", or "check dependencies"
- Wants to understand integration strength between modules or services
- Needs to identify problematic coupling or architectural smell
- Wants to know if a module should be extracted or merged
- References concepts like connascence, cohesion, or coupling from Khononov's book
- Asks why changes in one module cascade to others unexpectedly

## Process

### PHASE 1 — Context Gathering

Before analyzing code, collect:

**1.1 Scope**

- Full codebase or a specific area?
- Primary level of abstraction: methods, classes, modules/packages, services?
- Is git history available? (useful to estimate volatility)

**1.2 Business context** — ask the user or infer from code:

- Which parts are the business "core" (competitive differentiator)?
- Which are infrastructure/generic support (auth, billing, logging)?
- What changes most frequently according to the team?

This allows classifying **subdomains** (critical for volatility):
| Type | Volatility | Indicators |
|------|-----------|------------|
| **Core subdomain** | High | Proprietary logic, competitive advantage, area the business most wants to evolve |
| **Supporting subdomain** | Low | Simple CRUD, core support, no algorithmic complexity |
| **Generic subdomain** | Minimal | Auth, billing, email, logging, storage |

---

### PHASE 2 — Structural Mapping

**2.1 Module inventory**

For each module, record:

- Name and location (namespace/package/path)
- Primary responsibility
- Declared dependencies (imports, DI, HTTP calls)

**2.2 Dependency graph**

Build a directed graph where:

- Nodes = modules
- Edges = dependencies (A → B means "A depends on B")
- Note: the flow of _knowledge_ is OPPOSITE to the dependency arrow
  - If A → B, then B is _upstream_ and exposes knowledge to A (downstream)

**2.3 Distance calculation**

Use the encapsulation hierarchy to measure distance. The nearest common ancestor determines distance:

| Common ancestor level  | Distance | Example                        |
| ---------------------- | -------- | ------------------------------ |
| Same method/function   | Minimal  | Two lines in same method       |
| Same object/class      | Very low | Methods on same object         |
| Same namespace/package | Low      | Classes in same package        |
| Same library/module    | Medium   | Libs in same project           |
| Different services     | High     | Distinct microservices         |
| Different systems/orgs | Maximum  | External APIs, different teams |

**Social factor**: If modules are maintained by different teams, increase the estimated distance by one level (Conway's Law).

---

### PHASE 3 — Integration Strength Analysis

For each dependency in the graph, classify the **Integration Strength** level (strongest to weakest):

#### INTRUSIVE COUPLING (Strongest — Avoid)

Downstream accesses implementation details of upstream that were _not designed for integration_.

**Code signals**:

- Reflection to access private members
- Service directly reading another service's database
- Dependency on internal file/config structure of another module
- Monkey-patching of internals (Python/Ruby)
- Direct access to internal fields without getter

**Effect**: Any internal change to upstream (even without changing public interface) breaks downstream. Upstream doesn't know it's being observed.

---

#### FUNCTIONAL COUPLING (Second strongest)

Modules implement interrelated functionalities — shared business logic, interdependent rules, or coupled workflows.

**Three degrees (weakest to strongest)**:

**a) Sequential (Temporal)** — modules must execute in specific order

```python
connection.open()   # must come first
connection.query()  # depends on open
connection.close()  # must come last
```

**b) Transactional** — operations must succeed or fail together

```python
with transaction:
    service_a.update(data)
    service_b.update(data)  # both must succeed
```

**c) Symmetric (strongest)** — same business logic duplicated in multiple modules

```python
# Module A
def is_premium_customer(c): return c.purchases > 1000

# Module B — duplicated rule! Must stay in sync
def qualifies_for_discount(c): return c.purchases > 1000
```

Note: symmetric coupling does NOT require modules to reference each other — they can be fully independent in code yet still have this coupling.

**General signals of Functional Coupling**:

- Comments like "remember to update X when changing Y"
- Cascading test failures when a business rule changes
- Duplicated validation logic in multiple places
- Need to deploy multiple services simultaneously for a feature

---

#### MODEL COUPLING (Third level)

Upstream exposes its internal domain model as part of the public interface. Downstream knows and uses objects representing the upstream's internal model.

**Code signals**:

```python
# Analysis module uses Customer from CRM directly
from crm.models import Customer  # CRM's internal model

class Analysis:
    def process(self, customer_id):
        customer = crm_repo.get(customer_id)  # returns full Customer
        status = customer.status  # only needs status, but knows everything
```

```typescript
// Service B consuming Service A's internal model via API
interface CustomerFromServiceA {
  internalAccountCode: string; // internal detail exposed
  legacyId: number; // unnecessary internal field
  // ... many fields Service B doesn't need
}
```

**Degrees** (via static connascence):

- _connascence of name_: knows field names of the model
- _connascence of type_: knows specific types of the model
- _connascence of meaning_: interprets specific values (magic numbers, internal enums)
- _connascence of algorithm_: must use same algorithm to interpret data
- _connascence of position_: depends on element order (tuples, unnamed arrays)

---

#### CONTRACT COUPLING (Weakest — Ideal)

Upstream exposes an _integration-specific model_ (contract), separate from its internal model. The contract abstracts implementation details.

**Code signals**:

```python
class CustomerSnapshot:  # integration DTO, not the internal model
    """Public integration contract — stable and intentional."""
    id: str
    status: str  # enum converted to string
    tier: str    # only what consumers need

    @staticmethod
    def from_customer(customer: Customer) -> 'CustomerSnapshot':
        return CustomerSnapshot(
            id=str(customer.id),
            status=customer.status.value,
            tier=customer.loyalty_tier.display_name
        )
```

**Characteristics of good Contract Coupling**:

- Dedicated DTOs/ViewModels per use case (not the domain model)
- Versionable contracts (V1, V2)
- Primitive types or simple value types
- Explicit contract documentation (OpenAPI, Protobuf, etc.)
- Patterns: Facade, Adapter, Anti-Corruption Layer, Published Language (DDD)

---

### PHASE 4 — Volatility Assessment

For each module, estimate volatility based on:

**4.1 Subdomain type** (preferred) — see table in Phase 1

**4.2 Git analysis** (when available):

```bash
# Commits per file in the last 6 months
git log --since="6 months ago" --format="" --name-only | sort | uni

Related in Design