Topic
Testing & Quality
Tests, refactoring, static analysis, and quality practices that protect intent over time.
The Common Module Trap: Organize Code Around Concrete Capabilities
Delay common modules until ownership is clear, and organize logging, exceptions, and shared protocols around concrete capabilities instead.
How to Break Up a Giant Service Class Without Guesswork
Split an oversized service by mapping concepts, tracing responsibilities, testing boundaries, and comparing concrete refactoring options.
Create a Deliberate Messy Boundary to Keep the Core Clean
Contain unavoidable complexity in an explicit outer boundary so limited engineering time can protect the system's core concepts.
Layering That Teammates Can Understand—and the Build Can Enforce
Define stable layer roles, constrain optional upper layers, and automate checks only when a team needs stronger enforcement.
Name Readers, Finders, and Searchers by Behavior
Distinguish Reader, Finder, and Searcher classes by direct reads, added filtering, and composite searches rather than result count.
Earn Your Interfaces: Abstraction After Evidence
Start with concrete code, extract interfaces from proven variation, and keep one-to-one abstractions only when they create a real boundary.
Authorization Without Redundant Reads
Resolve the logged-in user once, keep access checks focused, and separate system-wide administration from channel-level permissions.
Don't Distort Production Code Just to Make Tests Easier
Change production code when its behavior becomes clearer or legacy code needs a testing seam—not merely to expose values or methods that only tests use.
Your First Test Can Be Messy—Refactor It Later
Start with the test that proves the behavior you care about, mock enough to make it run, and improve test design through repeated use and review.
Design Performance Tests from Real Traffic Shapes
Estimate volume and arrival patterns before choosing a load test, add deliberate headroom, and require evidence only where traffic risk justifies it.
Reliable Database Tests Without a Shared Test Database
Choose mocks, an in-memory database, Testcontainers, or a real database by the failure you need to catch, while keeping ordinary tests isolated from shared infrastructure.
Software Should Survive the Developer Who Built It
Good company software reduces debt, fits the team's operating ability, and remains understandable and repairable after its original developer leaves.
Unit Tests Should Preserve Business Intent
A business-layer unit test is useful when it guides design, records meaningful behavior, or makes the next developer reconsider a risky change.
Use Reader and Writer Components to Reveal Business Flow
Reader and writer components can hide storage details, narrow change, and let the business layer show policy, but only when the software's lifetime justifies them.
How to Split a Large Service Class by Responsibility and Layer
Use constructor dependencies and imports to diagnose an oversized service, then separate cohesive responsibilities before adding another architecture label.