
🔸 TL;DR
A “divergent change” smell happens when a single class/module must be edited for unrelated reasons (new field here, new format there, another endpoint later). It violates SRP, slows delivery, and breeds bugs. Slice responsibilities: extract classes/modules, group by reason-to-change, and add tests to lock behavior. 🚦
🔸 WHAT IT IS
▪️ One class changes for many unrelated reasons (UI tweak today, persistence rule tomorrow, integration detail next week).
▪️ Opposite of shotgun surgery (where one change touches many classes) — here many changes hit one place.
▪️ Symptom of missing boundaries and unclear responsibilities.
🔸 WHY IT HURTS
▪️ Slows you down: every edit navigates a maze of conditionals. 🐢
▪️ Increases risk: unrelated logic collides → regressions. 💥
▪️ Blocks parallel work: teams queue on the same file. ⛔
▪️ Kills readability: “God classes” with mixed concerns. 🌀
🔸 HOW TO SPOT IT
▪️ The same file is always in your PRs for unrelated tasks.
▪️ You frequently add if(feature) or switch(type) in one place.
▪️ The class imports everything (HTTP, DB, JSON, Cache, UI).
▪️ Unit tests feel impossible without heavy mocking.
🔸 EXAMPLE SCENARIO
▪️ OrderService knows about HTTP DTOs, discount rules, tax calculators, inventory checks, and DB mapping.
▪️ Adding a new discount or new channel both require touching OrderService, even though they’re unrelated.
🔸 HOW TO FIX IT (REFACTORING PLAYBOOK)
▪️ Extract Class / Module: split by reason-to-change (e.g., PricingPolicy, InventoryGateway, OrderMapper).
▪️ Introduce Interfaces/Ports: define boundaries (PricingPolicy, InventoryPort), hide details behind adapters.
▪️ Move Functions & Data: relocate logic to the module that owns it (cohesion ↑).
▪️ Replace Conditionals with Polymorphism: handle variations via strategy/factory instead of if/else.
▪️ Add Characterization Tests: freeze current behavior before you cut.
▪️ Create Feature Folders: group code by capability, not by technical layer only.
🔸 PREVENTION GUARDRAILS
▪️ Design with SRP (one reason to change).
▪️ Keep clean boundaries: domain ↔ infrastructure adapters.
▪️ Prefer composition over sprawling services.
▪️ Watch your metrics: file churn, growing method counts, cyclomatic complexity.
▪️ Review check: “Does this edit touch unrelated concerns?”
🔸 TAKEAWAYS
▪️ Divergent change = one class edited for many unrelated reasons.
▪️ It signals missing boundaries and low cohesion.
▪️ Refactor by slicing responsibilities and introducing ports/adapters.
▪️ Polymorphism beats giant conditionals.
▪️ Tests first, then safe, small extractions. ✅
#️⃣
#Refactoring #CleanCode #CodeSmells #SoftwareDesign #SRP #Architecture #DDD #Java #Microservices #Testing #Maintainability #TechDebt #DevEx #BestPractices
Go further with Java certification:
Java👇
Spring👇