We all know that things can get messy when writing code. You have an idea, you write it down, you discard parts of it, you have another idea, you add a quick fix to the previous idea, and all over sudden your code looks like a minefield. In this post, I am presenting methods to create a cleaner and more structured Flutter code by organizing code into different code blocks. While this post is specifically targeting Flutter, most of the key points should easily be transferrable to other languages also.
Grouping things together (Code Blocks)
At some point in each coding lecture or coding lesson, all of us were taught about different types of visibilities of methods, fields, attributes, constants, and so on. We are all aware that these things exist. However, as mentioned above, if we want to try something quickly, we usually ignore the good habits and write things down where we think they fit best (which is usually the section of the code we are starring at).
The main point of this post is that we should thoroughly have the discipline to group code together. That is what I am calling code blocks. The main three ways of organizing your code into code blocks are: grouping code together according to their logical function that code fulfills. Grouping the code according to the type that (mostly variables and members) have. And grouping code together according to the visibility.
Grouping by logical functions
Let’s fist look at grouping things together by their logical function. Just to give an easy example, all members regarding the redrawing functionality of a class would be grouped together. While this is seems nice to organize your code according to functionalities and it makes it relatively easy to put everything in one place when you are creating the code, I would consider it a bad code structure for two reasons:
- It is not easy to see which elements are exposed through a class when grouping them together by logical function. Public members and functions could appear anywhere in your source code file.
- Logical functions of members are different for almost every class. This means that there is no common element or structure where a reader could find something familiar in this code. (Also when we think about IDE support, trying to automate the grouping with the help of an IDE is next to impossible – see below)
Grouping by type
Another common grouping strategy is to organize all members by their type (and functions by their return type). This makes it easy when reading the code to find e.g. a bool as it is there with all the other bools in the bool-block of the source file. A problem that this strategy has, is that it is mixing the public members with the private members and thus creates a bit of a mess in the type blocks. The same goes for functions. I have seen code being organized by return type of the function so the reader can see what other methods in a class e.g. also return a bool. (Personally I am not a great fan of this grouping strategy).
Grouping by visibility
Lastly, the next strategy to create meaningful code blocks is grouping code by visibility. A while ago, I started to consequently organize my source code in visibility blocks (and spoiler alert – it is amazing). Each code file that I create has a public member block, a private member block, a constants block, a constructors block, a public methods block, and a private methods block. In my code, each of these blocks are opened by a big comment to indicate that everything below that comment is belonging to a new block is starting now. To be honest, at first this looked to me like a lot of boilerplate code comments, but after working with this for a while, it is really something that I wish every code I am looking at would have.
Especially after not having looked at a class or a code project for a longer time, organizing the code into visibility blocks makes it really easy to get back into the code and re-understanding what I was thinking about when writing it.
Another major plus of grouping code in a visibility block is that you can combine it with the other grouping strategies, by first grouping your code by visibility and then grouping it by function or type. In this way, you will have a clean top-level overview of your source file but also be able to group things together logically by functionality.
If you have made it until here, you are probably thinking right now: But this seems like a lot of work… Well, here is the good news:
Your IDE can help you with this
Yes, that is right! Your IDE is a powerful tool. But how can it help us to consequently group our code into code blocks? As mentioned above, we are doing this for grouping your code in visibility blocks. Here, your IDE can support you by autogenerating visibility blocks whenever you create a new file by using file templates. So whenever you create a new class, it will look like this:
Now all you need to do now is to be disciplined and write the members and functions into their appropriate visibility blocks. I am sure this will be helpful for you to create cleaner source code and increase readability.
As mentioned earlier, this article targets developing Flutter code, so I will give examples for how to build your file templates in the two main Flutter IDEs (Android Studio, Visual Studio Code).
Android Studio: You can create a file template for each type of file directly from the IDE. You simply go to File–> Settings…
And then navigate to “Editor”–> “File and Code Templates” and then find the standard “Dart File” template. Here you can easily insert your favorite visibility blocks arrangement. (In case you are wondering, I am using an 80 characters limit for my code block header comments).
Visual Studio Code: For VS Code we could also create file templates via plugins as we did in Android Studio, but let’s use a different cool native approach here: Let’s use code snippets. Code snippets are pre-defined (also dynamic) code blocks that can be inserted when pressing CTRL+Space. You know this from all the autocomplete functions that the IDEs have. VS Code enables us to define such code snippets ourselves, even without installing a VS Code plugin. Simply go to File–> Preferences –> User Snippets.
Here you will find an overview with all the file types that VS Code is capable of (depending on the plugins that are installed). Let’s assume you have the Flutter/Dart plugin installed, then a dart.json will show up where you can insert your Flutter-specific code snippet. You can see a full example in the image below. The “prefix” tag let’s you define the shortcut that you can use in your file to bring the code snippet up. In my case I was using v_block (visibility block), but you can chose that freely. See my example below:
Now when going back to the code and pressing CTRL+Space, you will see the visibility code block that you just defined show up (even including the comment that we defined in the “description” tag).
With snippets and file templates, you have now the tools to auto-generate visibility blocks, so you can start using them today. Btw: There is no excuse that your IDE might not support this, even VIM has this functionality 🙂
One more thing: Show and hide blocks when you don’t need them
As a final suggestion for using code blocks (not just for visibility blocks but also for logical or type blocks), you can use regions. In Android studio this is very simple (and can even be integrated into your new file template). Just add the following region code surrounding your code for the current visibility block:
//#region public // your code here //#endregion public
Android Studio will then let you collapse and expand your visibility block whenever you need it or don’t need it.
Unfortunately, in VS Code this is currently not natively supported for Dart, but there is a plugin (Region Folder) that helps you if you want to use regions for Flutter in VS Code also.
I know this is very coding meta, but I hope this helps you to think about structuring your code differently in your further or current Flutter projects. Please give this a try today to improve your code quality and readability.
Also please let me know what you think about this and if this helped you to improve your code readability.