2 years ago by James Hickey

Let me tell you a story





A company I was hired for as a Senior Developer was in what most would consider a crisis or at a crossroad. In the past, developers had near-zero communication with each other so that the products they were building were created in totally separate ways - with no expert guidance, code review, etc.





They had also spent about two-years allowing a "rockstar" developer re-engineer most of their products. Long story short, he was fired because he didn't want to communicate and share with other developers when the company decided it needed to foster a "team" mentality rather than have one developer drive all development. Come to find out what was re-engineered was actually a million times more complicated and tightly coupled than before!





All this to frame what the situation was when I started. Nobody really knew how the system really worked. There were no standards of development. There was no guiding organization or architecture when adding new features (e.g. free-for-all). Deployments involved some FTP'ing and multi-step process that could take up to 30 minutes - not to mention what happened when things were not "built" in the correct order. And the list continues...





One of the issues I tackled immediately was the idea of "where do I put my code?" What existed (i.e. what was re-engineered) was just too complicated. Adding parts to an existing feature took days, and sometimes weeks! 99% of that time was just figuring out where to put your code!





I will show you what I did to improve this situation - and brought what would have taken weeks to do down to days/hours.





How the typical app gets structured. And why that can be a problem.





Every company I've worked for that had an existing system in place organized their system/code by infrastructure. For example - most of these systems had a data access layer, a business layer (which was usually just a shell that deferred logic to the data access layer) and an application layer.





The application layer was the web app, which then called into the business layer and then finally into the data access layer. This is probably how most enterprise systems are organized.





Why is this bad? A few reasons:





Parts of the system (features) that need to be different due to the benefits of using other technologies or paradigms are usually dismissed as they don't "match" the governing architecture.

Finding specific features of a system are difficult because they are dispersed into multiple areas of the code.

Therefore, fixing or adding to existing features takes more time

It causes a disjunction between how developers understand and speak about the product and how everyone else in the company does.

The entire solution or codebase is "glued" together in a fundamental way.





Imagine you are a new developer for such a company. Think of the folder/structure of such an app (you might have one already opened on your other monitor right now). Just by looking at it from a high-level view - can you tell me what this app does?





What business problems does it solve?

What problems does your company care about?

What are the capabilities of the system?





You can't. At least, not easily. The code is organized by infrastructural concerns - not business oriented concerns.





A better way to organise and maintain code





How do we fix this? It's a very simple idea. It's just so different from what the industry has become automatic at doing. Organise your code by the products and features that your company actually makes!





For example, an e-commerce app might have features like (off the top of my head) "search", "browse", "cart", "payment", etc.





Imagine I asked you (a developer who's new to the team and product) to add a new feature: Allow users to pay using Bitcoin.





Could you figure out where you should start?





Yes, that's a rhetorical question.





What your app actually does vs. how it does it





The main point of this entire article is that you should focus on what your system can do and not how the system does it. Take for example a typical MVC structure:









Can you tell me what this app can do? What business problems does it solve? Where would you start to try and debug a certain feature?





Now, look at this:









What about now?





As a side note, if you are using an MVC framework (for example), then you can make each of these features it's own "mini" app:









Now your solution is primarily focused on the business domain you are trying to solve - and it just happens to be an MVC app.





Other Benefits





This leads to other benefits, such as:





Individual features can diverge in their implementation details if the need for different technologies is justified. Since they aren't locked into a structure that already determines the infrastructural organisation, specific features can evolve as needed.

The complexity of an individual feature is isolated and doesn't bleed into other "layers" or parts of the code.

Finding code for specific features or parts of a feature is super quick.

It forces developers to think about and focus on the business and product instead of how to shoehorn the goals of the business into a predefined and non-related structure.

The system as a whole is not as "glued" together as the typical paradigm would be.





To highlight the last point, many readers will note that this gives the flexibility of later hoisting these features into what most of us call "Micro-services".





If 70% of the site's traffic and overall load is targeted at the "search" feature (due to all the database queries needed or whatever) - we can "lift" this feature out of the codebase as it's own separate project (or module, package, etc.) and scale it by running multiple instances of this feature at run-time (using containers, let's say).





The remaining features, which are now 30% of the overall load, can potentially just be put on a cheaper server that still performs well enough.





Next steps





I would encourage you to try this strategy on your next project. Let me know how things work out by tweeting @jamesmh_dev!





If you are looking for more details and thoughts around these ideas I would suggest the following resources as starters:



