1.6 KiB
1.6 KiB
Contract: Module Atomicity
Version: 1.0
Principle
Each file has one clear responsibility. A file that does many unrelated things is a liability, not a convenience.
Rules
- One concept per file. A file should be nameable in a single noun:
user_validator.go,session_store.go,invoice_pdf.go. If the name requires "and" or "misc", the file is too broad. - Do not append new functionality to an existing file because it is nearby or already open. When a new piece of logic does not belong to the existing concept, create a new file.
- A file that grows past ~200 lines is a signal to split, not a mandate — but treat it as a prompt to ask whether all the code in it shares a single responsibility.
- Package-level
utils.go,helpers.go, orcommon.gofiles are banned. Name the file after what the code actually does.
Anti-patterns
- Adding a new handler to
handlers.gobecause there is already a handler there. - Putting unrelated functions in the same file to avoid creating a new one.
- A single file containing models, queries, business logic, and HTTP concerns at once.
- Files named after their location or role in the codebase rather than their concept:
api.go,misc.go,util.go,shared.go.
When to split
Split a file when:
- You cannot describe all of its functions in one short sentence.
- A new function you are adding does not share the domain of the existing ones.
- The file has more than one reason to change independently.
Do not wait until a file is "too big." Split at the moment the second responsibility appears.