From Amateur to Pro: 3 Layers of Separation for Your Codebase
Does your project directory look like a flat pile of files? You know the look: logic, headers, tests, and binaries all fighting for space in one folder.
In a university project, this is fine. But in a professional environment, this is called Source Pollution. It violates the core principle of Separation of Concerns.
Most tutorials teach you how to write code, but they rarely teach you how to build a product. When I started my first job, I didn’t know what a professional codebase looked like. But when I first cloned a company repository, I was amazed. I realized that being a Senior Engineer isn’t just about writing logic; it’s about architecture.
If a stranger looks at your repository, they should be able to navigate it in 60 seconds.
Here is the Three Layer Separation method that senior devs use to turn a “junk drawer” project into a production-grade system.
Layer 1: The Interface (include)
The first step in cleaning up source pollution is separating the What from the How. We do this by creating a directory called include.
This is where all your header files (.h) live.
Why do this?
This supports the concept of Encapsulation. The header files define the interface—they tell other developers (and other parts of the program) what the system can do, what functions are available, and what data structures exist.
By keeping these separate from the implementation, you are essentially telling your team: “Here is the menu of options you can use. You don’t need to worry about how the kitchen cooks the food; you just need to know what you can order.”
Layer 2: The Implementation (src)
Now that we have the interface, we need a place for the actual logic. This is the Source Layer. We create a directory called src.
This is where all your .c files live. This folder contains the implementation of the promises made in the header files.
The “Black Box” Benefit
When you separate implementation into a src folder, you treat your modules like black boxes.
For example, if you are working on connection.c, you might need to use some utility functions. You don’t need to open utils.c and scroll through hundreds of lines of code to understand how the logging works. You just look at utils.h in the include folder, see the function signature, and use it.
This cognitive offloading allows you to focus on your specific task without getting distracted by the implementation details of every other file in the project.
Layer 3: The Artifacts (bin)
The final sign of an amateur codebase is seeing the executable binary (e.g., a.out or my_tool.exe) sitting right next to the source code.
We want to direct all build artifacts—executables and object files—into a directory called bin.
The Makefile
To achieve this, you shouldn’t just run gcc manually. You should use a Makefile.
Your Makefile should be configured to:
- Look for headers in the
includedirectory. - Compile source code from the
srcdirectory. - Output the final executable into the
bindirectory.
This keeps your root directory clean. When you run make clean, it should wipe the bin folder, leaving your source code untouched and pristine.
Bonus Layer: Tests (tests)
Professional code is tested code. Instead of mixing test scripts with your main logic, create a tests directory.
This is where you place unit tests (e.g., test_connection.c). This separates your production logic from your quality assurance logic. It allows developers to validate the system without cluttering the main source tree.
The Result: A Professional Architecture
By applying these shifts, you move from a flat structure to a hierarchical one:
include/: The Interface (The “What”)src/: The Implementation (The “How”)bin/: The Artifacts (The Result)tests/: The Quality Control
Now, when a new developer joins your team, they know exactly where to look. They know where the headers are, where the logic is, and where the binary will appear.
Want to Audit Your Code?
I’ve put together a High IQ Software Checklist. It’s a free guide you can use to audit your codebases for logic, system architecture, and professional standards.
HenrikMDev.com/highIQ
Stop writing code like a student, and start architecting like a senior engineer.

