Don’t keep ‘em separated

Don’t keep ‘em separated
Multiple abstract shapes without clear separation between them

Languages that is. Separation of concerns has often been taught that the languages and technologies are where we should separate our concerns. In my 10+ years doing development, the amount of times I have needed my SQL separate from my backend code, or my CSS separate from my HTML code has been next to never. If you are separating your concerns this way, consider a new approach. Separation my job or feature.

Understanding Separation of Concerns

At its heart, the Separation of Concerns (SoC) is a design principle for organizing software into distinct sections, where each section addresses a separate ‘concern’. A concern is essentially any piece of interest or focus in a program. Why does this matter? Because, in the sprawling complexity of modern web development, keeping our code clean, understandable, and manageable is not just a luxury; it’s a necessity.

The Importance of Separation of Concerns

SoC is not just about writing code; it’s about writing stories. Each piece of your application tells a part of the story, and SoC ensures that these stories remain distinct and coherent. This clarity is not for the computer’s benefit—it doesn’t care how tangled our narratives become—but for us, the humans who spend more time reading code than writing it.

By dividing our applications into manageable, focused areas, we drastically improve our ability to maintain and evolve our codebase. Changes in one area, such as the data model, have minimal impact on others, like the UI. This isolation reduces bugs, simplifies debugging, and speeds up development, as teams can work on separate concerns simultaneously without stepping on each other’s toes.

The Misconception of Language-Based Separation in Web Development

Traditionally, we’ve been taught to split our concerns by language: HTML for structure, CSS for presentation, and JavaScript for behavior. While this approach seems logical, it fundamentally misunderstands the nature of our work. We don’t create websites or apps by neatly compartmentalizing structure, style, and logic. Our work is messier, intertwined, and ultimately, more holistic.

Take Angular, for instance. Angular’s component-based architecture encourages developers to think about UIs as a collection of isolated units. However, each component intertwines HTML, CSS, and JavaScript, challenging the traditional SoC model. Critics argue this blending muddles concerns, but I’d argue the opposite. Angular understands that the real ‘concern’ is the component itself—its functionality, appearance, and behavior as a cohesive unit. The issue with Angular, and similar frameworks, lies not in their lack of separation but in how they define a ‘concern.’

Reframing Separation of Concerns: Finishing Jobs, Not Tasks

The true power of SoC emerges when we focus on completing ‘jobs’ rather than performing ‘tasks’. Consider a developer tasked with adding a feature to a web application. If we adhere too rigidly to language-based separation, we risk fragmenting their focus across disparate files and folders, losing sight of the job’s overarching goal.

Instead, imagine if our focus shifts to finishing a specific job, such as implementing a user authentication feature. This feature spans multiple ‘concerns’—UI elements, styling, validation logic—but it’s a single, coherent job. By grouping all related aspects of this job together, developers can think in terms of features, not files, leading to more intuitive and maintainable codebases.

This approach doesn’t dismiss SoC; rather, it redefines it. It encourages us to ask: “What job am I trying to finish?” rather than “What specific task am I performing?” This mindset shift can lead to more effective organization of code, reducing the cognitive load on developers and enhancing collaboration within teams.

Conclusion

Separation of Concerns is a foundational principle in software engineering, but its true essence often gets lost in translation. It’s not about segregating code by languages or technologies but about organizing it in a way that reflects the real-world jobs we’re trying to accomplish. As web development evolves, so too should our understanding and application of SoC. By focusing on finishing jobs rather than ticking off tasks, we can create more robust, intuitive, and maintainable applications that stand the test of time.

In the spirit of continuous learning and improvement, let’s challenge ourselves to rethink our approach to SoC, embracing the complexity and nuance of building modern web applications. Together, we can write not just better code, but better stories.

Don't miss the next post