When starting the first career of being a software developer, apart from the knowledge gained from university or college, there is some more things needed to be aware of.
There was no requirement to write a good, maintainable code during the course works, we all only wanted to get the things done and pass the course. However, being in a career often means you will work in a team, and the project being worked on often needs to consider the project maintainability. One of it is to know how to refactor the code.
Here, I will give few examples in Python-like syntax and elaborate them. This is not representing any web framework, just for the ease of read.
Suppose you have a web app, and to write a feature that lets users to generate a table of data, let's say the staffs who attended the company annual dinner, and at the same time it counts the number of people who got the lucky draw.
Instead of having this:
def generateTable(): # Get data from a database named 'staffDB', # and get the records who attended annual dinner data = staffDB.totalStaffs.filter(attended_annual_dinner=true) # Write a formatted table and dump data in table = TableObject( header1="Name", header2="Got Lucky Draw?" ) table.header1.data = data.name table.header2.data = data.lucky_draw # Count the total number who got lucky draw lucky = data.lucky_draw who_got_lucky_draw = 0 for got_lucky_draw in lucky: if got_lucky_draw == "yes": who_got_lucky_draw += 1 # Ultimately, pass every data here to the webpage return('annual_dinner.html', data=data, table=table, who_got_lucky_draw=lucky_counts)
You can see, a function that carries three tasks:
- Get data from database
- Generate a table
- Count who got lucky draw
Although it does not seems complicated here, but in real world project this kind of writing style always ends up hundreds line of code.
It can be done in much simpler form:
def getAttendingStaffs(): # Get data from a database named 'staffDB', # and get the records who attended annual dinner data = staffDB.totalStaffs.filter(attended_annual_dinner=true) table = generateTable(data.name, data.lucky_draw) who_got_lucky_draw = getLuckyCount(data.lucky_draw) return('annual_dinner.html', data=data, table=table, who_got_lucky_draw=lucky_counts) def generateTable(name, lucky_draw): # Write a formatted table and dump data in table = TableObject( header1="Name", header2="Got Lucky Draw?" ) table.header1.data = name table.header2.data = lucky_draw return table def getLuckyCount(lucky_draw): # Count the total number who got lucky draw who_got_lucky_draw = 0 for got_lucky_draw in lucky_draw: if got_lucky_draw == "yes": who_got_lucky_draw += 1 return who_got_lucky_draw
This one splits into three functions, each one performs single task. Only when the
getAttendingStaffs() function is called, it will also call two other functions and pass the required parameters in.
Although this results more line of code in total, but it surely make the code tidier, and easier to navigate when you need to modify the function.
Take an example in real world project, there is a bug in generating the table. The former style makes you search through a long line of code that wraps everything into a function, and the code looks messier in overall; the later style you can only focus on that particular function, better focus.
The idea of this one is similar to the one above, but make it in the file-level.
In other words, create source files based on its scope of job. Instead of one source file performing few jobs, separate the jobs into few source files.
For example, you have a blog website, and users can have account to write their blog posts. In this case, you can create a few source files, where one stores all the global constants, one does the job of handling user account information, one does the job of handling posts. Lastly, you have a main source file (as entry point) referring those files and they work together.
Doing so keeps the logic away from a single file. So, in future maintenance, perhaps you want to have a new feature that allows users to upload an image to a post, just mess with that source file, the others are unaffected.
Often we need to write a conditional statement to control how an application behaves. If you are writing a simple conditional statement, using negation statement is often recommended.
Well, this does not really make the code significantly less cluttered, but apart from what textbook taught (a conventional if-else style), we can make the code looks a little bit cooler.
Instead of this:
def someFunction(): if somethingPositive: # Do this return(someValue) else: # Do that return(otherValue)
Make it like this:
def someFunction(): if somethingNegative: # Negation IF # Do this return(someValue) # Proceed to do desired tasks
Perhaps an example is easier to understand, we have a boolean variable called
def doActionByStatus(): if not status: # Perform tasks if status is false text = "The system is not functioning properly." return(text) # Perform tasks if status is true text = "All systems are performing well" return(text)
Don't worry about the function will proceed when
false and the tasks inside are executed. After the function reaches the first
if statement, it will exit. Else, the function will just do the tasks after
Alright, hope this article can help junior developers and freshgrads in their careers. There are a lot of writing practices that helps writing better, cleaner and more maintainable code.
If you can do these as a habit, when your next juniors come and work with you, they will thank you.