Code structure
Where do I start?
Now you know what your goals should be, you’ve thought about some design principles to guide your implementation, and you know what the architecture should look like.
What’s next? How do you actually get started?
You know that:
- You need layers for your user-interface, domain and model.
- You have features that are orthogonal to these layers e.g., your recipe application will probably need to fetch data (model and persistance), modify and repackage it into a useful structure (domain) and display it (view).
Do you write all of your views first? Do you build models first? What to do?
Vertical slicing
In software development, vertical slicing
is an approach where a feature or functionality is developed and delivered end-to-end in a single iteration. Unlike traditional methods that focus on building software layer by layer (horizontal slicing), vertical slicing carves out a fully functional piece across all layers or aspects of the application – right from the user interface down to the data access layer.
We recommend vertical slicing
.
Why do this?
- It aligns your design and code with your user stories and features. You can build related features together, which will result in a more cohesive design.
- You are delivering working functionality each iteration. You can demonstrate (and get feedback) on a specific feature set.
- You have working code faster, which reduces risk in your project (compare this to horizontial scaling, where you might build an entire layer, but can’t actually demonstrate features until you integrate all of the changes later in the project).
Horizontal slicing
The counter to veritical slicing
is horizontal slicing
where you build entire layers at a time. This approach would suggest that you build the entire model + persistance layer, separate from the user-interface layer. You would leave integrating these layers (and adding user features) later in the project.
There is a time and place for horizontal slicing, typically when you’re building a library or framework to address specific technical needs. For example, maybe your data is so complex that you need a robust model in place to do anything. That might warrant building out most of the Model ASAP. However, even in this scenario, I would recommend dividing your labour: have some people continue building features (vertically) and they can provide API feedback while the Model is being built.
In most cases, vertical slicing
will give you better results since it focuses on delivering testable features.
How do I structure my source code?
This is a vertical structure.
Each feature is a top-level package, and within that package, you have sub-packages for the different architectural layers.
e.g. a recipe application with both a card (detail) view and a list (summary) view of recipe data. The lowest level packages would contain the relevant classes for that package.
.
├── main
│ └── kotlin
│ ├── recipe-card
│ │ ├── domain
│ │ ├── model
│ │ └── userinterface
│ └── recipe-list
│ ├── domain
│ ├── model
│ └── userinterface
This has a major advantage in that each feature is isolated and testable within its own namespace. i.e., you can write unit tests that check the model, domain and UI classes for a particular feature and ensure that they work well together.