Improve readability by having clean codes

Nandhika Prayoga
7 min readMay 14, 2020

--

Clean space

Everyone can become a programmer, but not all programmers are software engineers. Programmers could make any application they want and so do software engineers, not only software engineers could make codes but also they could maintain their codes because they know how important it is to have well-made codes in terms of readability.

In this article, I want to share with you based on my experience with my team how we achieve readability codes by having clean codes. Since I’m a front-end engineer and I work on React, then I will share with you how we achieve that in React. Don’t worry I try to apply global guidelines in order to have clean codes, so it should be applicable for any language as well. Enjoy!

Names

Names are the most important thing when we do code, a good name will help you to understand code even though you don’t know about the implementation. That’s why it’s powerful.

Okay, so basically there are two types of naming convention for function, constant, and class, namely snake_case and CamelCase. Here, see examples of snake_case and CamelCase

// snake_case
weight_total = 20
// CamelCase
weightTotal = 20
weight = new Human(weight=weightTotal)

So in snake_case, you should use small letters and split each word by underscore. CamelCase split each word by nothing and each word must have capital in their first letter, if it’s a variable, then the first letter must not be in the capital.

You could use it either one of them only or use both of them together. Perhaps some of you think “Hey, you should not use both of them together!”, yes I kind of agree with you, but in fact, that really happens in the real world, did by a lot of professionals. In python as an example, they use CamelCase for class, other than that they use snake_case.

Variable name

A variable is the most basic thing in Programming, and I think almost every line codes will use variable since they store a value/state we want to use, so it’s important to know how to write it properly. This how we write variable in our project:

// Python (snake_case)
filterset_fields = INVESTIGATION_CASE_FILTERSET_FIELDS
// JavaScript (React) (CamelCase)
const [innerValue, setInnerValue] = useState(value)

You notice in React we use const (means you couldn’t do mutation on it) but consider it as a variable, why? because we see the innerValue as the value that could be changed by restating the variable, even without a mutation. In the next section we will see how we differ variable and constant even though we use both of them with const in React.

Constant name

So I think to define constant on any language should be in the same way, personally I don’t really see this naming convention from snake_case or CamelCase, let’s see the example below!

// JavaScript(React)
const DEFAULT_THEME = {
colors: {
black: 'black',
red: 'red',
},
};

You see that we use capital for each letter and split each word by underscore. It’s quietly the same as snake_case but not really the same and not quietly same as CamelCase too.

You also see we use const for both variable and constant, but since it has a different name format you still can tell which one is variable and which one is constant. More technical, how we see constant is truly a value that will never be changed, so it’s regardless of the syntax and that’s what happens on DEFAULT_THEME.

Function name

Same as we write name for a variable, nothing more special than that. Let’s see an example!

// Python (snake_case)
def perform_destroy(self, instance):
instance.delete(author=self.request.user.account)
// JavaScript (React) (CamelCase)
function validateForm(fields: RealFieldsType): boolean {
return Object.keys(fields).reduce((
isValid: boolean,
fieldName: string
) => {
return isValid && fields[fieldName].isValid;
}, true);
}

You see we totally use CamelCase in React, not only variable but also function. For python, we use snake_case same as how we define the variable too

Class name

In any language, we always use the same convention name for a class, like this

class InvestigationPositiveCaseAPIView(ListAPIView):
serializer_class = InvestigationCaseSummarySerializer
permission_classes = (IsAuthenticated,)
pagination_class = PageNumberPagination
filterset_fields = INVESTIGATION_CASE_FILTERSET_FIELDS
search_fields = INVESTIGATION_CASE_SEARCH_FIELDS
ordering_fields = INVESTIGATION_CASE_ORDERING_FIELDS

Even you use snake_case for variable and function, in a class, you should use CamelCase. That’s why some languages with snake_case as their convention name is so confusing when they also have class.

Data structures

Having a clean code could be achieved by the data structure we use. For example, if you use an Array, then as a fellow developer you know what the capability of Array, you know it could edit element in specific index with complexity time O(1) and delete an item with complexity time O(N), or if we are talking about the functionality you know you could store a list item with the same type, and so on. By using a common data structure like this, it could be able to communicate with your fellow developers what you try to scope and achieve.

That’s why it’s important, let me show you my work.

interface CategoryButtonProps {
values: Array<ItemType>;
// ... other props
}
export default function CategoryButton({
values = [],
// ... other props
}: CategoryButtonProps) {
const [innerValues, setInnerValues] = useState(values);
return (
// ...
)
}

You see there in bold, there is value with an Array type. By seeing this you have feeling it will be used to show a list of items in view and you know it has a potential that could be filtered, be sorted, or add a new item. You can guarantee, there is no way to delete an item on Array with time complexity O(1). Simple as like that, sometimes it easy to communicate with your fellow developers.

Programming Style

You need to set your mind what programming style you want to use because it will affect the tools you will use or pattern you will use on your codes, so indirectly it will affect to the aspect of readability as well.

As far as I know, there are only two options we could use in terms of programming styles, namely procedural programming and functional programming. In simple words, procedural programming based on OOP and functional programming based on functional-oriented. By you set one of these options in your mind it will scope you from the way you code, it will ensure you do code with provided tools and related patterns. so if there is another developer see your codes with the same paradigm you use for creating that codes, usually both of you will understand instantly without really knowing the implementation.

In my team, we used functional programming in front-end (JavaScript) and procedural programming in back-end (Python). I already wrote an article about how we used functional programming in front-end in here, feel free to read if you want.

Code Rules

There are some rules to evaluate how good your codes are, but I only want to share with you two properties of codes, namely high cohesion, and low coupling. Perhaps you wonder the correlation with clean codes. So first high cohesion lets you have related codes in function or class, which means will increase the readability aspect. Same as low coupling, it lets you to have codes that focus only on what its can do regardless of other codes' existence (independent).

So it doesn’t matter the language or programming style you use, you only need to keep in mind always those two properties when doing code. This is an example of what we did in front-end, so we have global components and we define each of them to be independent as possible and made them do their responsibility. Let’s see!

Global components

I believe you can tell what each component does only by its name.

This is an example of Gap component looks like.

import React from 'react';
import styled from 'styled-components';

enum Axis {
Horizontal = 1,
Vertical = 2,
}

interface StyledGapProps {
paddingTop: number;
paddingBottom: number;
paddingLeft: number;
paddingRight: number;
}

function isVertical(axis: Axis) {
switch (axis) {
case Axis.Horizontal:
return false;
case Axis.Vertical:
return true;
}
}

const StyledGap = styled.div`
position: relatve;
display: flex;
flex: 0 0 auto;
padding-top: ${(props: StyledGapProps) => props.paddingTop}px;
padding-bottom: ${(props: StyledGapProps) => props.paddingBottom}px;
padding-left: ${(props: StyledGapProps) => props.paddingLeft}px;
padding-right: ${(props: StyledGapProps) => props.paddingRight}px;
`;

interface GapProps {
axis: Axis;
gap: number;
}

function Gap({ axis, gap }: GapProps) {
return (
<StyledGap
paddingTop={isVertical(axis) ? gap / 2 : 0}
paddingBottom={isVertical(axis) ? gap / 2 : 0}
paddingLeft={!isVertical(axis) ? gap / 2 : 0}
paddingRight={!isVertical(axis) ? gap / 2 : 0}
/>
);
}

Gap.Axis = Axis;
export default Gap;

Pretty straightforward right? it only has one responsibility and doesn’t depend too much on other codes.

Takeaways

That’s it, there are still more I want to share with you actually but I’m afraid you read this article too long, I think at another time I will continue this article. I hope you get more insight from this article and you could do better than me to code in your project and work. Thank you!

--

--

Nandhika Prayoga

Mainly a Full-stack Developer, Software Architecture Engineer. I'm a passionate developer, love to learn new things and write an article about it