Bringing order in files

One of the main paradigm we followed during Fitradar application development was Object Oriented Programming paradigm. And the main objectives of OOP are:

  • to organize the code in such a way that data and functions using its data stick together in one entity (class),
  • to extract reusable parts in separate entities (classes interfaces).

And as we followed the OOP principles and patterns our big code evolved in to many small files, each representing one or sometimes several entities. Each file contained clean and well organized code that was easy to maintain. From one hand we reduced the size of the files and such improved the navigation within a file but increased the number of files. And the more files we produced the more harder it became to navigate between the files. And very quickly it became clear that we need a new way how to organize our code-base files that anyone could quickly find a needed file. And since there are several ways how to organize the files in packages and the source code packaging really depends on the project, in this article I wanted to share our teams experience on how we found a way that helped us to find file quicker in our code base.

The goal of organizing files in packages is to allow a developer or any other person who is working with a source code easily find a needed data type. In order to achieve this we had to introduce particular principles on how to organize files within a packages. And once a person learns these principles it should be a breeze for him to find a necessary type. When we thought about it, we came to conclusion that these principles should act like search algorithm but for human. The basic partition of our source code in separate projects was predefined by Clean Architecture. It gave us a basic understanding where to put files on the high level. In our first attempt we tried to put the same type data under the same package. For example all the repositories definitions we kept in package com.fitradarlab.fitradar.domain.repository, all the retrofit endpoint definitions we kept in package com.fitradarlab.fitradar.data.net.endpoints and so on. This kind of approach introduced by Clean Architecture worked well in data and domain projects, but when we tied to apply it to the UI project it didn’t really helped us. And the reason was the way how we worked with UI part of the project. Our work was organized around the use cases. And to implement a use case on the UI level we had to work simultaneously on Activity, Fragment, ViewModel, Dagger dependency Module, layout and navigation. All these types were located in different packages and under each package there were already quite a few other files and therefore it was hard to find a needed file fast. First to mitigate the problem we tried to keep all the files of a use case opened, but we realized quickly that the more files we open in Android Studio the less we see of a file name in a tab because it shrinks. So even on our big screens we could have only 5-7 files opened, but in many cases we needed more than that. It was not right away that we noticed that the files we try to keep opened belong to one use case, but once we realized that it became clear that we need to put those files under the same package. Once this discovery was made the new packaging structure for UI project was born. We completely refactored UI project by introducing packages that reassemble the names of our use cases. And thanks to Android Studio refactoring tools it took only a few hours, and after that we really felt comfortable with the new packaging structure. Now we didn’t have to keep the bunch of file opened because all the files we needed to work with were visible under the single package in Project window.

New UI project package structure

But there was still one problem left – the resources files. Contrary to source code where developer can create a hierarchy of packages the resources have only several predefined folders and the most used resource types like layouts and drawables usually have long list of files. And once again we applied the use case approach and came up with following naming convention for our layout files: the layout file starts with the type – fragment, activity, row or view, then we mimic the name of the package and the name ends with unique name of the layout. For example the layout for our timeline page has the name fragment_sport_event_timeline.xml. Unfortunately we still can’t find a good naming strategy for drawables and other shared resources that are not bind to particular use case, but already now with these new naming conventions we see a noticeable improvement in our source code maintenance.

Visit our website and join the mailing list. Our app is coming soon:

http://fitradar.me/

Leave a Reply