• 20 hours
  • Easy

Free online content available in this course.

course.header.alt.is_video

course.header.alt.is_certifying

Got it!

Last updated on 6/17/24

Write clean functions

Defining a good quality function

How do you write quality functions? It requires both designing your code components effectively, and clearly identifying elements.

What is a function to begin with? Here are a few guidelines to follow:

First, if two or more lines of code repeat more than one time, it should be a function. Check out the example below:

// feeding a person
Console.WriteLine("Break 2 eggs on a pan"); 
Console.WriteLine("Add chopped vegetables"); 
Console.WriteLine("Stir occasionally for 2 mins");

// feeding another person
Console.WriteLine("Break 2 eggs on a pan"); 
Console.WriteLine("Add chopped vegetables"); 
Console.WriteLine("Stir occasionally for 2 mins");

// OR

// define a function
public void MakeOmelet()
{
   Console.WriteLine("Break 2 eggs on a pan"); 
   Console.WriteLine("Add chopped vegetables"); 
   Console.WriteLine("Stir occasionally for 2 mins");
}

// feeding a person
MakeOmelet();

// feeding another person
MakeOmelet();

Second, if the code becomes lengthy and hard to navigate, it’s best to put it into a function even if it only needs to be executed once. If the content of your function doesn't fit on your development screen, and you can’t follow the logic of it at a glance, it's likely too long. Fifty lines could be a good arbitrary reference point:

// A long chunk of code - 50+ lines 
// replace with functions
public void PerformTheBeginning()
{
   // 50 or less lines of code
}

public void PerformTheEnding()
{
   // 50 or less lines of code
}

PerformTheBeginning();
PerformTheEnding();

Finally, if you have a function that completes more than one task, you should split it up into smaller functions. From there, make another global function that calls those smaller ones. For example, you need a payment transaction to do two things: save the transaction, and notify the system to perform the related updates:

public void ProcessPayment()
{
   // save transaction
   // notify the system
}

// instead, split in sub-functions
private void SaveTransaction()
{ 
}

private void NotifySystem()
{ 
}

// and call them both
public void ProcessPayment()
{ 
   SaveTransaction();
   NotifySystem();
}

Purposed-based is another function classification:

  • Interface (behavior) functions - These are called by external elements. An example would be the ProcessPayment method.

  • Helper functions - These are created for internal convenience and readability. Examples are the sub-functions created within the payment processing function.

Let's look at another example using car objects. The interface functions are the behaviors a class needs to implement for external use such as:

  • Drive

  • Turn

  • Start

  • Stop

The helper functions could be:

  • CalculateSpeed

  • StartEngine

  • StopEngine

The interface functions must be sufficient to use an object to its expected capacity. The helper functions need not be visible to the external code, and should be clearly architected within the class.

Formatting the code

Formatting plays a significant role in defining the quality of your code and can be separated into the following components:

  • Naming

  • Commenting

  • Writing style

Each is important and needs to be used wisely.

Naming

Naming is one of the essential components of good quality code and consists of two parts:

  • Coming up with a name.

  • Following naming conventions.

Coming up with a name is not a trivial task. The name you use must reflect the purpose of your function. Its name must say what it does.

For example, if a you have a drivable car object, you could have a function called drive or  makeCarMove. You could also name it move, but it's not as clear. 

In a class that generates geometrical shapes, you could have shape-making functions and call them makeSquare or makeRectangle. As you can see, using the prefix make in this example is more appropriate than in the previous one.

The same concept applies to naming parameters of a function. Just like any other variable, a parameter's name should reflect its purpose:

public void Paint(Car car, String color) // Encouraged
{
}


public void Paint(Car c, String clr) // Discouraged
{
}

Additionally, it's important to follow naming conventions. Those depend on the programming language and your development team.

In C#, use the Pascal case naming convention. As you may recall from a previous chapter, the first word in a function or class starts starts with an uppercase letter. The first word in the names of variables starts with a lowercase letter. 

public void CreateShape() // Correct
{
}

public void createShape() // Incorrect
{
}

Commenting

Comments explain what is not understood by reading the code. It could also include some extra tips. The most common examples are:

  • Why - Explaining why a certain implementation approach was chosen over another, especially if the other appears to be a stronger choice.

  • Tips - Extra tips include such things as available options within the class functionality being used from outside.

There are two types of comments:

  • Single-line

  • Multi-line

Single-line comments are defined by using a double forward slash // at the beginning of the comment. The rest of the line is considered a comment:

// Single line comment

Those are used for short notes. If the line wraps on a typical developer environment screen, consider multi-line comments. Using multiple single-line comments is appropriate for short comments if they are contextually different. Alternatively, a single multi-line comment is more appropriate.

Define multi-line comments by using an opening and closing combination of characters /* and */ respectively:

/* First line of multi-line comment
second line of multi-line comment 
*/

Writing style

Writing style refers to how you arrange the components of your code.

There are few common battles that have no right or wrong answers:

  • Using spaces - here're a few examples:

int a = 10;
a = a * 21;
// comment

versus:

int a=10
a=a*21;
//comment
  • Same line or new line braces:

if (true) {
}
else {
}

versus:

if (true) 
{
}
else 
{ 
}
  • Tabs vs. spaces to format intent within the files.

Both variations of each group are acceptable and depend on your team. Mixing them is a big no-no. The team should have a unique writing style that everyone follows. However, you will frequently fix and improve the existing code. In this case, it's best to follow the existing style used by previous contributors.

Try it out for yourself!

Ready to get started? To access the exercise, click this link.

Let's recap!

In this chapter, we've covered the basic aspects of writing good quality functions:

  • Rules to follow when deciding what should be a function:

    • When two or more lines of code need to be executed more than once.

    • When a chunk of code is too large to grasp and doesn't fit on a screen.

    • When a function completes multiple tasks, use assisting sub-functions.

  • Functions are classified into two categories:

    • Interface functions - those that expose the class functionality outside of the class.

    • Helper functions - convenience functions that are used within the class and improve architecture and readability.

  • Formatting is an important component of the good quality code. It includes:

    • Following naming conventions

    • Commenting

    • Using a consistent writing style

Example of certificate of achievement
Example of certificate of achievement