Coupling, Decoupling, and Cohesion

Published: (February 9, 2026 at 11:29 AM EST)
4 min read
Source: Dev.to

Source: Dev.to

Cohesion describes how well the code inside a file, function, or module belongs together.

  • High cohesion – everything inside does one clear job.
  • Low cohesion – a random mix of unrelated stuff.

Analogy

Imagine your kitchen drawer:

  • Low cohesion – a messy junk drawer with spoons, batteries, tape, old receipts, and a phone charger all mixed together. Finding anything takes forever.
  • High cohesion – a well‑organized drawer where cooking tools are in one place, cleaning supplies in another. Easy to find, easy to use.

Kitchen drawer to explain coupling and cohesion

JavaScript example – low cohesion (avoid this)

// utils.js – does everything (bad!)
function calculateTotal(price, tax) {
  return price + tax;
}

function sendEmail(to, message) {
  console.log(`Email sent to ${to}`);
}

function getUserAge(birthYear) {
  return new Date().getFullYear() - birthYear;
}

function saveToLocalStorage(key, value) {
  localStorage.setItem(key, value);
}

This file does math, emailing, age calculation, and storage. Hard to understand, hard to test, hard to fix.

High cohesion (better)

// priceCalculator.js
export function calculateTotal(price, taxRate) {
  const tax = price * taxRate;
  return price + tax;
}

export function applyDiscount(total, percent) {
  return total * (1 - percent / 100);
}

One file = one job (price math). Clean and focused.

Coupling – “How much do modules know about each other?”

Coupling measures how connected two pieces of code are, i.e., how much one part depends on the internals of another.

  • High / tight coupling – modules are glued together.
  • Low / loose coupling – modules talk nicely but don’t know too much about each other.

Analogy

Lego bricks vs super‑glued blocks:

  • Lego bricks snap together easily and can be pulled apart to rebuild (low coupling).
  • Super‑glue makes every brick permanently attached; changing one piece breaks the whole thing (high coupling).

Visual – good vs. bad coupling

Cohesion vs coupling

  • Left: everything connected to everything → hard to change.
  • Right: small groups connected only when needed → easy to work with.

JavaScript example – tight coupling (bad)

// userService.js
class UserService {
  getUser(id) {
    // Directly knows it's using localStorage (tight!)
    const data = localStorage.getItem(`user_${id}`);
    return JSON.parse(data);
  }

  saveUser(user) {
    localStorage.setItem(`user_${user.id}`, JSON.stringify(user));
  }
}

This code is glued to localStorage. If you later want to switch to a server or IndexedDB, you must change this file and every place that uses UserService.

Loose coupling (good) – using dependency injection

// storage.js (interface‑like)
export class LocalStorageService {
  get(key) { return JSON.parse(localStorage.getItem(key)); }
  set(key, value) { localStorage.setItem(key, JSON.stringify(value)); }
}

// userService.js
export class UserService {
  constructor(storageService) {
    this.storage = storageService; // just uses the interface
  }

  getUser(id) {
    return this.storage.get(`user_${id}`);
  }

  saveUser(user) {
    this.storage.set(`user_${user.id}`, user);
  }
}

// Usage
const storage = new LocalStorageService();
const userService = new UserService(storage);

Now UserService doesn’t care how storage works. You can easily swap it for:

class ApiStorageService {
  async get(key) { /* fetch from API */ }
  async set(key, value) { /* send to API */ }
}

This is decoupling – removing the strong glue between parts.

Decoupling – The Action of Making Coupling Loose

Decoupling means actively reducing how much modules depend on each other’s details.

Common ways in JavaScript:

  • Use function parameters instead of global variables.
  • Pass dependencies (dependency injection).
  • Use interfaces / simple objects instead of concrete classes.
  • Use events / callbacks instead of direct calls.
  • Separate files by responsibility.

Why Should You Care?

Good cohesion + low coupling = your code is like Lego:

  • Easy to understand – one file = one clear idea.
  • Easy to change – swap one piece without breaking others.
  • Easy to test – test small parts in isolation.
  • Easy for teams – different people can work on different pieces.
  • Easy to grow – add new features without chaos.

Bad cohesion + high coupling = your code is like a house of cards made of super‑glue:

  • A tiny change can break many parts.
  • The system becomes fragile, hard to maintain, and difficult to extend.

Places

  • Hard to test
  • New developers get scared
  • Bugs hide everywhere

Quick Rule to Remember

Aim for:

  • High cohesion inside each module (one job per file/function)
  • Low coupling between modules (talk through simple contracts, not internals)

Next time you write JavaScript, ask yourself:

  • “Does this function/file do one main thing?” → Cohesion
  • “Does it know too much about other parts?” → Coupling

Keep practicing these ideas – your future self (and teammates) will love you for it!

0 views
Back to Blog

Related posts

Read more »