10 Practical Approaches That Shape My Work in Software Architecture
After 13+ years in software architecture, I’ve defined 10 key practices that help deliver predictable, maintainable software—covering design structure, process, team setup, and infrastructure. Here's how I keep complexity under control and systems built to last.

For over 13 years, I’ve worked in various software architecture roles—across startups and established companies alike. I’ve focused on projects with long-term development goals, because that's where good software design really makes a difference.
Over time, I’ve refined a set of working practices that help ensure stable execution, technical clarity, and predictability in delivery. Especially in recent years, my approach has evolved further, shaped by both advanced training and the lessons learned from real project work.
Here’s what I rely on:
1. Avoid Splitting by Functionality
One of the most impactful changes I made was to stop decomposing systems by business functions. Instead, I identify areas that are likely to evolve independently—grouping logic around those axes of change. This method leads to a code design that localizes change and protects the overall structure from ripple effects, supporting long-term maintainability.
2. Maintain Separation of Concerns in Code
Even with a solid architectural model, it’s easy for the actual implementation to drift. I enforce separation of concerns by putting clear boundaries in the code design, especially when it comes to dependencies between modules. This keeps complexity in check and ensures that architectural intent is preserved over time.
3. Stay Out of Feature Development
It may sound counterintuitive, but I intentionally avoid building features. Developers should own the domain. As an architect, I stay focused on structure and delivery. Getting involved in individual features creates distractions and pulls attention toward short-term urgency at the cost of long-term system health.
4. Build a Custom Application Infrastructure
Creating infrastructure components tailored to the project’s needs is how I bridge design and implementation. These are abstracted building blocks that simplify the work of feature development teams, reduce duplication, and standardize behavior. This kind of foundational setup makes writing unit tests and adding new features much easier.
5. Shape the Development Process
Good software design alone isn’t enough. The process matters too. I actively work with teams to define how design, development, and validation happen. It’s important to create space for technical design to happen independently, and to structure work in a way that aligns with the system’s complexity and business priorities.
6. Use an Activities Network, Not a Task List
Instead of linear backlogs, I plan around a network of activities and dependencies. This approach improves visibility for all roles—developers, managers, testers—and helps us manage change effectively. It’s a practical tool that supports predictable delivery in dynamic environments.
7. Actively Support Project Staffing
Staffing decisions directly affect technical outcomes. I collaborate with PMs to plan who joins the team, at what point, and with what level of experience. Matching skills to the structure of the system—rather than leaving it to chance—can significantly improve delivery quality and speed.
8. Communicate Progress Early and Often
Early in the project, there's little visible functionality. Still, I make sure to show progress—milestones in setting up tools, making architectural decisions, or validating approaches. Keeping stakeholders informed helps build trust and reduces unnecessary pressure on the team.
9. Delay Features Until the Foundation Is Ready
Most of the initial work in a serious project is foundational: CI/CD setup, infrastructure, and system design. That’s deliberate. Once enough groundwork is in place, I look for opportunities to start building features in parallel. Done right, this staged delivery helps manage risk without delaying visible outcomes.
10. Estimate Time and Cost with Structure
Reliable estimates require more than guesswork. I correlate the activities network with staffing plans to produce grounded forecasts. This helps manage expectations and leaves room to adapt. Predictability comes from this discipline—not just optimism.
Final Thoughts
These practices help me keep a clear focus on design quality, technical clarity, and the ability to deliver predictable results. Whether it’s through clean code design, structured estimation, or modular infrastructure that supports unit testing, these principles give me the tools to build systems that scale and last.
Drawing from our extensive project experience, we develop training programs that enhance predictability and reduce the cost of change in software projects.
We focus on building the habits that make developers adopt the industry best practices resulting in a flexible code design.