Writing beautiful code is often underestimated, especially by inexperienced developers. The main reasons are that writing beautiful code takes more time, and you won’t see its benefits right away.
What is beautiful code?
Beautiful code is clean, well-organized, and simple to upgrade. It is easy to read, understand, and navigate. To create and maintain such code, I follow eight simple principles.
1. Have coding standards
Coding standards are a set of coding rules. There is no universal coding standard, every product team might have its own written and unwritten rules. Among important ones, I would mention guidelines for
- naming variables & naming methods,
- how to group methods & how to group classes,
- the order of writing methods,
- how to import dependencies,
- how to store data, so you would have a uniform code in every class.
You know to have good coding standards when you look at the code of other developers from your team and can’t recognize who wrote it.
This kind of code is more comfortable to understand. Coding standards give you consistency in all the projects you are working. If you are looking at some project from your company for the first time, you’ll know where to search the content you need. In the long term, coding standards save you a lot of time — from reviewing the code to upgrading features you haven’t worked on before, because you know what to expect.
Let’s see some good and bad examples of naming variables and methods:
Now one more example of Do and Don’t for grouping your methods:
Also, when talking about coding standards, don’t forget the organization of your workspace. To navigate quickly, you have to organize your project functionally: create groups of files that relate to each other. Keep the same organization for all projects. So if you work on multiple projects, you don’t have problems with finding the resources you want.
2. Use self notation
This can be coding standard too, but I wanted to point out a few things about the concept.
Firstly you have clear perspective what is global and what is local variable for the current scope. Although Xcode sets the different color for global variables, that isn’t good enough distinction for me. When using self notation, it’s much easier to recognize it.
In the other hand, if you have code with many handlers, you have to use self notation inside them. Using it outside of handlers too makes your code uniform.
3. Use marks for easier navigation
Marks are used for dividing functionality into meaningful, easy-to-navigate sections. And yet, not all developers are not using them. There are two types of marks in terms of preview with and without dash (-). Marks with it are preceded with a horizontal divider.
We use marks with das for creating sections, and if you want to create subgroups, we use marks without the dash.
Again, like in the first section, this code is easier to understand, navigate, and review. Code without marks or methods placed in the wrong section, shouldn’t be approved at the review.
There shouldn’t be any strings or any other constant in your classes. Constants are pieces of information that don’t have much value so you shouldn’t pay attention to it. Moreover, they can be quite long, in another language, so it makes your code unreadable.
What you should do is to create a file with constants, create a coding standard for naming constants, group them using marks, and then use them in the classes. One more benefit of constants is that you can reuse them, and if there is a need for change, there is only one place to do it.
5. Class size
Depending on the project you are working on, you should predetermine class size. Ideally, a class shouldn’t be longer than 300 lines, without comments, but there will be exceptions, of course. Small classes are much easier to understand, manage, and change.
To have small classes first, you have to think about architecture. In standard MVC it’s tough to have controllers that are smaller than 300 lines. That’s why you should try with other types of architecture like MVVM or Viper. There, controllers aren’t so massive because they are only responsible for presentation logic. Business logic is in other files.
However, be aware. Readability should always be the priority relative to class size. Your functions should also be small, easy to read and understand. You should have a maximum number of lines for function, and if the function has more lines than allowed, you should refactor it. Let’s see on practice:
6. Create reusable components
One more trick for having smaller, easier to understand classes is to create reusable components with the following characteristics:
1. It handles business processes
2. It can access another component
3. It’s relatively independent of the software
4. It has only one responsibility
Import those components in other classes. I already wrote about this topic in How to implement the service-oriented architecture. Look at it for more details.
7. Design patterns
For solving some problems, there are already excellent solutions — design patterns. Each pattern is like a blueprint that you can customize to solve a particular problem in your code, and after a little bit of practice, quite easy to understand and implement. Design patterns make communication between developers more efficient. Software professionals can immediately picture the high-level design in their heads when they refer to the name of the pattern used to solve a particular issue.
Every app needs a different set of patterns, but there are common ones that every app should implement — delegation, observer, factory, dependency injection.
8. Code review
While the primary purpose of code reviews should be functionality, we also need to take care about readability and organization of the code. If the code doesn’t compile to these principles, reject a pull request.
Some tools can help you with code reviews like SwiftLint or Tailor, so I highly recommend using one.
Code reviews can take some time, but they are an investment for the future. New developers will learn these principles by reviewing your code, and by getting your feedback about theirs. Moreover, the clean code will save you time when you come back to change feature after a few months.
Be strict when reviewing and expect it from others when reviewing your code. If you don’t do so, you’ll create an atmosphere that it’s ok to make mistakes. Don’t merge code if it has flaws. Chances are you are going to forget to fix them.
The functional aspect of the code is an essential part of developing an app. However, to easily maintain and upgrade an app, the code has to be clean, organized, easy to read, understand, and navigate, or as we called it here beautiful.
These are the principles I use to make my code beautiful. It sure takes more time to write and review, but it will save you more in the future.