DEV Community

Cover image for 6 coding best practices for beginner programmers
ericaeducative for Educative

Posted on • Updated on • Originally published at educative.io

6 coding best practices for beginner programmers

Code is written once. Then it's read, debugged, refactored, and scaled constantly. How you write code today will help you maintain and scale the application later down the road. We’re frequently under the pressure of deadlines in software development.

Regardless, it’s important to use coding best practices to help ensure better quality code for yourself and for anyone who may have to extend that code in the future.

Today, we’ll discuss the importance of using coding best practices, and six best practices you should know as a beginner programmer.

We’ll cover:



Why you should use coding best practices

As a coder, developing a coding style that’s mindful of these best practices will make it easier to extend and debug the code in the future. Even if you’re no longer working with that codebase, the legacy of your work will affect the community of developers who work with that code in the future.

Coding best practices help ensure code quality and codebase health. Using good practices when writing code will support the characteristics of good code, that is: Maintainability, scalability, readability, and portability.

Code is written once and read thousands of times.

Some good coding practices, such as commenting, don’t affect the functionality of a program. However, they do impact the experience for the humans who’ll be reading and maintaining that code. You may be able to get your program to execute, but if you don’t implement best practices, a quickly done task can backfire by creating confusion and problems in the future. Writing good code now will help ease the processes of code reviews, unit tests, and refactoring.

6 coding best practices for beginner programmers

1. Code indentation

Proper indentation is the most important thing you can do to ensure that your code is readable and easy to understand. There are many different indentation styles, such as K&R, OTBS, and Stroustrup. These styles all advise that we add spaces and new lines in our code, so that each block of code is readily identifiable.

In the following code example, it’s difficult to identify the boundaries of functions, loops, and conditional blocks without proper indentation:

#include <stdio.h>
int find(int A[], int size) { int ret = -1; for(int i = 0; i < size; i++) {
if(A[i] > ret){ ret = A[i];
}
  }
   return ret;}
int main() { int A[]={1, 4, 7, 13, 99, 0, 8, 5}; printf("\n\n\t%d\n\n", find(A, 8));
return 0; }
Enter fullscreen mode Exit fullscreen mode

In the following example, we rewrite this code with proper indentation. It becomes much easier to understand.

#include <stdio.h>
int find(int A[], int size) {
   int ret = -1;
   for (int i = 0; i < size; i++) {
       if (A[i] > ret) {
           ret = A[i];
       }
   }
   return ret;
}

int main() {
   int A[] = {1, 4, 7, 13, 99, 0, 8, 5};
   printf("\n\n\t%d\n\n", find(A, 8));
   return 0;
}
Enter fullscreen mode Exit fullscreen mode

2. Meaningful naming

Your code’s variable names and function names should be intuitive. Ideally, we should be able to guess what a function does based on the function’s name.

You should give intuitive names to objects, variables, classes, functions, and constants. However, we also strive to keep our code concise and readable. If the most intuitive name is too long to keep code concise, you’re welcome to use its shorthand. Just be mindful that the shorthand should remain intuitive as well.

The following example of code does not follow meaningful naming conventions. This makes it difficult to understand and reuse.

#include <stdio.h>

int find(int A[], int size) {
   int ret = -1;
   for (int i = 0; i < size; i++) {
       if (A[i] > ret) {
           ret = A[i];
       }
   }
   return ret;
}
int main() {
   int A[]={1, 4, 7, 13, 99, 0, 8, 5};
   printf("\n\n\t%d\n\n", find(A, 8));
   return 0;
}
Enter fullscreen mode Exit fullscreen mode

In contrast, the following code example has the same functionality, but meaningful naming makes it easier to understand.

#include <stdio.h>

int findLargest(int inputAry[], int inputArySize) {
   int largest = -1;
   for (int loop = 0; loop < inputArySize; loop++) {
       if (inputAry[loop] > largest) {
           largest = inputAry[loop];
       }
   }
   return largest;
}

int main() {
   int A[]={1, 4, 7, 13, 99, 0, 8, 5};
   printf("\n\n\t%d\n\n", findLargest(A, 8));
   return 0;
}
Enter fullscreen mode Exit fullscreen mode

3. Comments that add context

Code is for the compiler, while comments are for coders.

Even if other best practices are accounted for, source code can’t always be self-explanatory. When code can’t explain itself, comments should step in. Here, good practices for writing stories apply to writing code: The more you anticipate your reader’s thoughts, the more impactful your comments will be.

Here are some general guidelines for code comments:

  • Prioritize quality over quantity: Don’t go commenting on every line of code. Comments should still support code readability. If your function name or variable name already infers what is happening, you don’t need to let readers know.

  • Don’t assume your reader has context: Let your readers know the context behind the code so they can understand why each part is necessary. If you’ve modified code to fix a bug, comments help keep that bug fixed.

  • Explain the “Why”: Don’t tell us what we can already see in the code. Explain the why behind it. We can see which method or function you’re using, but knowing why helps readers better understand the code.

Code commenting helps make codebases and projects more maintainable. When done well, good commenting can streamline code reviews. Comments also support developer onboarding by helping newcomers familiarize themselves more quickly with a codebase.

The following is an example of code commenting done well.

#include <stdio.h>

/**
* Finds the largest integer from the given array (inputAry)
* of size (inputArySize).
*/
int findLargest(int inputAry[], int inputArySize) {
   //Assumption: array will have +ve elements.
   //Thus, the largest is initialized with -1 (smallest possible value).
  int largest = -1;

   // Iterate through all elements of the array.
  for (int loop = 0; loop < inputArySize; loop++) {

      //Replace largest with element greater than it.
      if (inputAry[loop] > largest) {
          largest = inputAry[loop];
      }

  }
  //returns the largest element of the array
  return largest;
}

int main() {
   int A[]={1, 4, 7, 13, 99, 0, 8, 5};
   printf("\n\n\t%d\n\n", findLargest(A, 8));
   return 0;
}
Enter fullscreen mode Exit fullscreen mode

4. Don’t repeat yourself

Also known as the DRY principle, “Don’t repeat yourself” strives to reduce code duplication. The idea here is that if you have code that’s doing the same thing twice, it should be made into a function. By abstracting code into functions, you can reuse that code and make development more efficient. In addition, avoiding code duplication makes debugging easier, as you won’t have to fix a bug in every instance of repeated code throughout your program.

5. Low coupling and high cohesion

Low coupling and high cohesion are different yet complementary principles. Low coupling encourages separation between unrelated parts of a codebase, while high cohesion encourages integration between related parts of a codebase.

low coupling

They may sound like opposing principles, but low coupling and high cohesion work together to ensure the maintainability, scalability, and testability of our applications. High cohesion strives to keep a close relation between units that need to know about each other. When it’s time to extend code, we benefit from finding related code in the same places. On the other hand, low coupling strives to reduce dependencies between unrelated units.

If we don't follow this best practice, we risk trending toward high coupling and low cohesion. This results in excessive dependencies, which has several negative impacts. One undesirable result is an increased vulnerability to bugs, as a bug in one unit will affect its dependent units as well.

high coupling

Low coupling and high cohesion apply to how we treat any of our language constructs, from methods and classes to libraries and APIs. These good practices can be achieved through what are known as SOLID principles in object-oriented programming.

6. Consider your context

Coding guidelines vary across different contexts. Depending on your programming language, company, or industry, there may be different coding guidelines for naming conventions, coding style, indentation, and file structures. Be mindful of your project’s individual needs and honor those coding standards when you can.

Use your best judgment, and adjust to whatever your situation calls for.

It's important to know good coding practices, but rules are simply generalizations without context. To be used well, they need your good judgment. Keeping all these principles in mind, you should follow your instincts as a programmer. There will be times where your context challenges a general principle, and you know your case best. This is what others mean when they say not to take these rules “pragmatically,” and we agree.

Wrapping up and next steps

Writing good code is essential to your success as a developer. By keeping these coding practices in mind, you can ensure that your code is easier to maintain, scale, and debug. The more you code, the better you’ll get at applying and adapting these practices across different languages and projects.

To master more best practices for your coding career, check out the Coding Career Handbook. This course covers everything from writing quality code to career strategy for junior through senior developers.

Happy learning!

Continue learning about coding on Educative

Start a discussion

What best practices have you been using? Was this article helpful? Let us know in the comments below!

Top comments (0)