Structure your code by feature

cross-post from bbv blog

When software projects grow both in age and size the developers often struggle with the structure of the code. It gets more and more difficult to find the class you have to change for a new requirement. In this post, I’ll show you how we organize our code and how we derive our structure directly from the requirements.

When you look at example code from the internet or how some frameworks (e.g. ASP.NET MVC) structure their code, you see that they most likely organize the code by layer or put classes of the same kind in the same place.

For example in Model-View-ViewModel and ASP.NET MVC samples you will see namespaces/folders named Views, ViewModels, Controllers, Entities, DataTransferObjects, Repositories and so on.

Layers they say!

Now, we all were told that layers are good. Mainly because they simplify the code due to the fact that layers higher in the hierarchy are only allowed to access layers further down in the hierarchy. That’s okay, but has nothing to do with structuring code.

Feature Features!

I made the experience that structuring code by feature results in a much simpler layout. The main reason for this is that all the classes you are currently working on are physically near to each other despite their kind. The view, view-model and so on of the customer search are all in the same place: under the namespace MyCompany.MyProduct.Customers.Search. Thus minimizing navigation in the solution explorer (Visual Studio). Furthermore, these namespaces do not grow when the software grows, only the number of namespaces increases due to new features being implemented. Now when I have to look for a class then I start by looking up the feature it is needed in, go to this namespace and find it there.

The namespace per feature approach gives you some additional advantages:

  • when a feature has to be removed you can “simply” remove the namespace as a whole and you do not have to search through all the layer based namespaces
  • the structure of your code reflects the features and not the technologies used (watch Architecture Deference to see why this is important)
  • refactoring namespaces (e.g. introducing sub-features) is simple because only the feature you are currently working on is affected

“But what about assemblies?”

Remember that assemblies are used to deploy a program on a machine. If you have a client and a server you’ll need at least two assemblies, probably at least three because of shared code. But this is a completely different decision than structuring. When you split up your code into different assemblies to deploy to different sites, you should still use the same namespaces in these assemblies. Start with changing the default namespace in the project settings.

Agile, Scrum, User Stories, Product Backlog and getting a structure by feature

When you develop software in an Agile way and your requirements are given in the form of User Stories then deriving features and therefore namespaces is really simple.

  1. Identify the Themes in your Product Backlog  (see Themes/Epics/User Stories)
  2. Per Theme introduce a namespace. E.g. MyCompany.MyProduct.Theme1
  3. Identify features within each Theme. Often these features are initially described by Epics. E.g. searching, editing
  4. Per identified feature introduce a namespace below the Theme: MyCompany.MyProduct.Theme1.Feature1
  5. When namespaces grow too big, introduce sub-namespaces according to sub-features. Always try to think in user actions and not in technological differences.

“But what about infrastructure code?”

Yes, there is code that is used by several features. This code should be put into the existing namespace per feature hierarchy and not into its own. You got this right when you don’t need to add using statements into each code file (.Net,  import for Java).

Code shared by MyCompany.MyProduct.Theme1.Searching and MyCompany.MyProduct.Theme1.Editing should be in MyCompany.MyProduct.Theme1.

But my assemblies get really big! That slows me down because the time needed to build increases, especially when practicing Test Driven Development!”

I develop software test driven. That means that I build my code and run tests every few seconds (I try at least). Build time gets very important. Additionally, Visual Studio and Resharper don’t reward you with good performance once a project reaches a certain size.

Therefore, assemblies need sometimes to be split up even if deployed at the same location.

When splitting assemblies you should consider the principles of package design and you should split along feature/namespace boundaries. If you split by feature the code and the number of projects that have to be built to run a unit test is minimized; thus minimizing the time you have to wait for the test to run.

“But the framework I use already dictates me to use namespaces like view or viewmodel!”

You have two options: look for another framework or start with a namespace per feature inside the namespaces that were given by the framework. E.g. MyCompany.MyProduct.View.Theme1.Feature1

So, how do you structure your code? And why? Let me know in the comments section.

About the author

Urs Enzler

12 comments

  • Urs,
    Very interesting this post (actually all your blog), congratulations…

    I understand the point, but I don’t see a thing clear…
    You say “I made the experience that structuring code by feature results in a much simpler layout. The main reason for this is

    that all the classes you are currently working on are physically near to each other despite their kind. The view, view-model

    and so on of the customer search are all in the same place: under the namespace MyCompany.MyProduct.Customers.Search. Thus

    minimizing navigation in the solution explorer (Visual Studio).”

    How can you minimize navigation in the solution explorer (VS) in a VS solution with many VS projects?
    E. g., MyProduct_PL.exe, MyProduct_AL.dll, MyProduct_DL.dll and MyProduct_IL.dll
    (PL = PresentationLayer, AL = ApplicationLayer, DL = DomainLayer, IL = InfrastructureLayer)
    Creating a folder on each project? (each project would have the namespaces as you recommend).
    A folder like “Theme1.Editing” or “Theme2.Search” in MyProduct_PL.exe with view, another folder on MyProduct_AL.dll with

    application service, another on MyProduct_DL.dll with entities and value objects and another on MyProduct_IL.dll where they

    live repositories, NH mappings, …

    Or perhaps I should not have “as many” projects?
    Yes to the logical layers but not as many fisical tiers.
    E. g., MyProduct_Client.exe and MyProduct_Server.dll, also performing a work of layering.

    Thanks very much,

  • Why did you split your code into these dedicated layer oriented assemblies?

    If these assemblies are not installed on different tiers I suggest to consolidate as many as possible into a single assembly. Then navigating gets a lot easier as explained.

    Cheers
    Urs

  • Why? :mmmm Damn books and frameworks!!!! :-p

    After “talking” to you (wait! Was it a secret? X-D) I restructured my current project in only one project (also because the project must end now before the agreed): will be deployed with ClickOne on each client PC. Only database will be on the

    server.
    Anyway, despite being a single project, I have views and presenters (PL), entities and value objects (DL), repositories and NH

    mappings (IL), … One physical tier, several logical layer.
    Have you wondered for this, right?

    What I like to have as many projects is the “power” of scope classes:
    I can create a public class in a layer and hide to the world – with internal scope – several classes because they are an

    implementation detail, ensuring that nobody can never instanciate/reference them accidentally.
    With a single assembly, internals = public

  • This is an interesting idea. Are there any open source projects out there with this structure? I’d like to visually see a bit better what you are referring too. I can understand and agree with parts of it but things like shared base classes / common services / etc don’t seem to fit. Unless you have some core/shared libraries and then jump into Feature X / Feature Y.

  • @Nathan Palmer
    Unfortunately, I don’t know any open source projects following this approach that is big enough to get a picture. My open source project bbv.Common follows these principles, but it’s a library and there, everything is easy anyway.

    And infrastructure code can often be extracted into a library style package of its one, thus defining its own technical “feature” and therefore namespace. That how bbv.Common started 8 years ago.

  • @JC
    Yes, you can’t hide classes anymore. But regarding extensibility it was never a good idea to hide them anyway.
    I deal with this situation by putting these kind of classes into ‘Internal’ namespaces.

    This has also to do with the way you build up your application. We always use some kind of IoC container. Therefore, all implementation classes have to be accessible by the binding definition, which permits internal anyway because bindings should be specified at a place as high up in the dependency graph as possible.

  • Hear Hear. I’ve seen a few projects with a load of assemblies like Product.DTO, Product.DAL, Product.BusinessLayer, etc, and they are awful to work on – a change such as adding a field needs you to touch files in 4 or 5 different places and recompile all those projects. Structure by feature is much nicer.

By Urs Enzler

Recent Posts