DEV Community

Cover image for The Life-changing (And Time-saving!) Magic Of Feature Focused Code Organization!
James Hickey
James Hickey

Posted on • Updated on • Originally published at builtwithdot.net

The Life-changing (And Time-saving!) Magic Of Feature Focused Code Organization!

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 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 organize 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. Organize 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. (It should go into "payment" 😉)

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:

mvc

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:

mvc

What about now?

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

mvc

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 organization, 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:

Vertical Slice Architecture
Solid Architecture: Slices Not Layers (Video)
Clean Architecture

P.S. This was originally featured on builtwithdot.net's blog

Navigating Your Software Development Career

An e-mail newsletter where I'll answer subscriber questions and offer advice around topics like:

✔ What are the general stages of a software developer?
✔ How do I know which stage I'm at? How do I get to the next stage?
✔ What is a tech leader and how do I become one?

Sound interesting? Join the community!

Top comments (23)

Collapse
 
jonhilt profile image
Jon Hilton

100% agree with this. I've been using feature folders (and MediatR) to build everything as vertical slices for a few years now and couldn't go back!

I really wish Microsoft and Co would change their new project templates to help developers fall into the pit of success.

Collapse
 
jamesmh profile image
James Hickey

Thanks for feedback Jon!

I'm on board with you. I know Angular tries somewhat to do this... Would be nice to have the backend frameworks try? lol

Collapse
 
atsteffen profile image
atsteffen

Absolutely agree! Group by feature not layer (or technology)! This is perhaps the biggest and most impactful lesson I've learned in my programming career.

I think one of the reasons more teams don't adopt this is partly because it can be challenging to do without higher level tools that help you visualize your modules and their dependencies. It's a lot easier to throw things together by their file extension than by their conceptual cohesiveness, especially if you have no way to visualize and reason about cohesiveness. I don't think I would be able to do it at scale without Structure101 or similar tool.

Collapse
 
jamesmh profile image
James Hickey

I think the biggest problem is that devs are disconnected from the business. Devs are too focused on the technical problems they are solving instead of focusing on the business problems they are solving.

If that was the focus, then organizing your code around the business's products or features just naturally flows out of that.

I think the hard part is that it's such a (poor) standard in the industry to just build all these layers (which are horizontal instead of verticle).

I agree - these types of higher level concepts or "tools" (whatever you want to call it) have been the #1 thing that has made me stand out and get to where I am in my career.

I also don't feel like I'm running around in the dark as much!

Collapse
 
makingloops profile image
Joe Petrakovich

These ideas make so much sense but I also feel a bit of sadness because I know my old ways and ideas have to die :)

Do you think new strategies like this are only just now becoming available because of Moore's law?

Collapse
 
jamesmh profile image
James Hickey

Hahaha!

If I did have to guess, I think this one, in particular, has to do with the tendency for software developers to get too engrossed in the technologies / technical specifics of what they are doing rather than trying to understand how the business works.

Most devs after-all, I suspect, really have no interest in the business itself, but just want to "build stuff".

Collapse
 
mark_nicol profile image
Mark Nicol

That is such a fresh way of thinking about it. I think you've just reshaped my head. What a useful way of thinking about the next codebase I'm looking at.

Collapse
 
jamesmh profile image
James Hickey

Awesome! Def. let me know how things go when you get a chance to do this kinda stuff 👍

Collapse
 
cjbrooks12 profile image
Casey Brooks

Individual features can diverge in their implementation details if the need for different technologies is justified...specific features can evolve as needed.

This point cannot be understated. when working with horizontal layer, poor design choices affect the entire codebase, and it's difficult to fix (or even understand) the problem. But if a feature slice chooses a poor implementation, well just cut your losses and don't do it again on the next feature. The rest of your app is safely isolated from the design patterns in other features, and you have the freedom to try new things with little risk overall.

Collapse
 
jamesmh profile image
James Hickey

Def. agree - having done this on anonymous the team mentioned in the article it's such a breathe of fresh air that new features can introduce new concepts or not use concepts that have been found to be non-beneficial.

So for teams who want to experiment with different ways to structure code etc. it's a fantastic way to do that.

In my case, I'm slowly introducing new concepts like CQRS, Domain Driven Design, etc. to the team - inch-by-inch as new features are built. Works great!

Collapse
 
pulljosh profile image
Josh Pullen

This actually feels really similar to the types of design shifts made by React.

First, with JSX, code was split by feature rather than language. (Instead of dividing code into content, styles, and functionality, it's divided by feature -- by component.)

A similar type of shift has been made by the introduction of hooks. Instead of dividing a component's code by lifecycle methods, it is divided by the functionality it supports.

Both changes were controversial at first, but have grown to seem like an obvious best solution over time (more of that yet to come for hooks, I'm sure). Hopefully in the coming years we can learn to better identify and correct backwards (perpendicular?) code separation...

Collapse
 
imronlearning profile image
Michael Learns

Wow! I've actually implemented a similar structure to a few of my side-projects and definitely it made it easier for me to decide where to new features or find where certain code was. I had no idea it was actually that helpful 😅 Totally agree with this!

Collapse
 
joppedc profile image
JoppeDC

That Coravel Pro piece of kit looks great! We have a similar in-house tool that allows us to do that stuff but in PHP, and it really helps :D

Collapse
 
jamesmh profile image
James Hickey

Nice! It's good to get some feedback around that.

Are there any specific abilities of the product you have that you find the most important/helpful?

Collapse
 
joppedc profile image
JoppeDC

Most usefull thing is probably the scheduler. Allowing people to simple click 'add scheduled task', and letting them enter command name, options and a schedule.
Also the fact that when scheduled jobs fail, you can see the exact console output of that command when it ran

Thread Thread
 
jamesmh profile image
James Hickey

Cool - ya that's a very helpful utility, instead of relying on manually setting up a cron entry for one schedule etc.- or even code based scheduling which does require a re-deploy for compiled languages.

Collapse
 
suckup_de profile image
Lars Moelleken

at work we have different directories for "app/modules/" (e.g.: shop/cart, bill/, ...) and something that we call "framework/modules/*" (e.g.: system/authentication, ...)

Collapse
 
nhh profile image
Niklas

I highly recommend this kind of slicing! Thats what i always do before i get into code, figuring out what my app will do rather than how it is done. Everything else are details. Very good advice! 👌😊

Collapse
 
chiangs profile image
Stephen Chiang

In what ways does this differ from the microservices pattern?

Collapse
 
jamesmh profile image
James Hickey

Microservices are when individual "features" or "areas" of your product are independently deployable to their own process/run-time - usually done using containers or VMs.

Breaking your code-base into vertical slices by feature is a necessary pre-cursor to scaling out microservices. But you can do this in a monolith (as described in the article) and gain the benefits mentioned in the article.

If you read the final section of the article "Other Benefits" I briefly discuss this idea.

Thanks for the feedback!

Collapse
 
qm3ster profile image
Mihail Malo

asks a rhetorical question
confirms it's rhetorical
answers it

Collapse
 
jamesmh profile image
James Hickey

Sometimes you never know - better to be a clear as possible 😂

Some comments may only be visible to logged-in visitors. Sign in to view all comments.