How should code be organized in an enterprise application?
By Mike Trzcianowski
Imagine you're a general contractor who has been hired to install a new fridge with an ice-maker at a single-family house.
Just from the outside, you notice that the house is a little strange. All the doors and windows seem to be on one corner of the house. You walk in and notice that the first room has 10 ceiling lights, 15 light switches on the wall and 30 electrical outlets, but otherwise it's empty. The room next to it has 4 sinks, 2 toilet bowls, 1 shower, a garden hose, etc. Another room is full of furniture with beds, sofas, chairs, desks and tables.
You scratch your head and wonder. Where do you put the fridge? How do you connect the fridge to the outlet in one room and to the water pipe or sink in the other room?
This example illustrates the situation I usually encounter when I start working on an existing code base. The developers have organized the code and assembled in terms of data layer, business layer and UI. It's great, isn’t it?
Now, imagine you scale the same problem from a house to a hotel. You have 200 sinks in one room and 500 light switches in another room. The electrician is installing a new A/C unit but, well, his time is limited, so he hooks it up to the first electrical outlet he finds in the "electrical stuff" room. Then he runs a drainpipe to the first pipe in the "plumbing stuff" room. When he turns the A/C unit on it's a disaster.
Why do software developers do this? There are multiple reasons why this happens. Some of them are:
Reason 1: It’s easy to do organize code into layers but more difficult to organize by function.
A reasonably well-written class can be easily classified as data, business or UI layer. On the other hand, the same class could be used by multiple components and in such case it is more difficult to decide whether it belongs in one, the other, or maybe on its own. In other words, it’s easier to decide whether a piece of code belongs in one of three or four layer buckets, than in an undetermined number of feature buckets.
Reason 2: Developers assume that layer organization is equivalent to project or assembly organization.
That is not usually the case. In web projects, your UI might be a web page, whereas the business logic might be inside of a web service. However, the web service will usually include business and data logic. In 99.9% of the times, you don’t need a separate data layer assembly because you will not be supporting multiple interchangeable databases.
Reason 3: Most code examples and project templates are for simple projects.
When starting a new project, you might see some folders created automatically for you, such as Controllers, Views, Repositories, etc. This may be sufficient for a small project or component, however, once you start adding multiple features, the basic structure no longer works because you have everything intermingled.
So, how should code be organized in an enterprise application?
Rule 1: Organize by feature and not by layer.
Imagine you are adding a new shipping feature to an order processing system. If everything is organized by layer, you have to dig through the different classes and decide what you need from the data and business layers. On the other hand, if you organize by feature, you can easily find all the classes for managing orders and products in their respective areas.
The additional benefit, especially in an enterprise system, is that it’s easier for different components to have separate databases or even storage mechanisms. This is important because you can now distribute, scale, or test specific parts of the application without having to deploy the full application.
Rule 2: Separate layers by namespace and not by project or assembly.
It’s much easier and more efficient to deploy a single assembly that includes all the components for a feature, while deploying multiple layer assemblies when you really use only a subset of each. Use assemblies only when the code in each assembly is deployed independently.
Rule 3: Keep it agile. Keep refactoring.
Don’t overthink the organization. You may still begin with a single component with layers separate into folders or namespaces. But as you add different features to your application, you will need to rethink how the code is evolving. Don’t just throw new code into the layer folder. The same principles you apply to a class may be applied to a component. Encapsulate logic that relate to the component and push unrelated logic into separate components or namespaces — just think of the single-responsibility principle, but at a higher level.
In summary, what works well for a simple app, may get you in trouble with an enterprise solution. It’s easy to get complacent and not touch existing code. But that is a trap. You need to rethink the evolution of the application structure as you add more and more components. Having the code organized into layers is better than no organization at all.
However, this isn’t enough for an enterprise application where components need to be reusable for different areas. Plus, don’t forget to think about the work involved in maintaining the application in the future. It takes effort to come up with a good organization for the code. The time spent now will pay dividends in the future. It’s a lot more difficult to come back to legacy code and figure out how all the classes are related to each other. Instead, organize the code as it is added and provide a visible structure that can be easily seen later without having to dig deep through the code.
Comment below to let us know your thoughts on successful code scaling and to find out more about our software development capabilities.
References and related articles:
“Features and Components” - http://scaledagileframework.com/features-components/
“Mapping software architecture to code” -http://www.codingthearchitecture.com/2013/04/08/mapping_software_architecture_to_code.html
“Package by Feature, not layer” - http://www.javapractices.com/topic/TopicAction.do?Id=205
“Scalable code organization in AngularJS” - https://medium.com/opinionated-angularjs/scalable-code-organization-in-angularjs-9f01b594bf06“Single Responsibility Principle” - https://en.wikipedia.org/wiki/Single_responsibility_principle