General Concepts in Code Writing

Why Clean Code?

  • Code readability is a problem that can lead to difficulties in maintenance.

  • Clean code is easily understood by everyone on the team, promoting readability, changeability, extensibility, and maintainability without accumulating technical debt.

  • Technical debt, according to Martin Fowler (2003), is a metaphor for the consequences of "doing things the quick and dirty way," which sets up a debt similar to financial debt.

  • A code smell is a surface indication of a deeper problem within the system.

  • Refactoring is a disciplined technique for restructuring existing code to improve its internal structure without altering its external behavior.

  • Failing to write the best implementation from the beginning can lead to costly code rewriting later in development.

  • Spaghetti code is a source code with a complex and tangled control structure that is difficult to understand and maintain. It's considered an anti-pattern.

Pasta Theory of coding:

  • Lasagna code - Code with multiple layers of abstraction, making it hard to follow the control flow.

  • Ravioli code - Code with many small, loosely connected modules, making it difficult to understand the overall structure.

  • Macaroni code - Code with long, winding, and complex structures, resembling a strand of macaroni.

Code Smells

  • Examples: Duplicated Code, Long Methods/Functions, Large Classes/Modules, Comments that indicate a code smell, Inconsistent Naming Conventions, Unused Code, Complex Conditionals, Lack of Error Handling, Excessive Nesting, Primitive Obsession

Duplicated Code

  • Repeating the same code in multiple places leads to maintenance problems and increases the risk of introducing bugs.

float area_of_triangle(float base, float height) {
    return 0.5 * base * height;
}

float area_of_rectangle(float width, float height) {
    return width * height;
}

// Duplicate code below
float area_of_square(float side) {
    return side * side;
}

Long Methods/Functions

  • Functions that are too long can be difficult to understand and may indicate the function is doing too many things.

  • A function should be doing a specific task. If it’s doing 2 or more, decompose them to smaller tasks for code reusability.

Large Classes/Modules

  • Large classes or modules can make code difficult to understand and may indicate the class/module is doing too many things.

void process_orders() {
    // Code to retrieve orders from database
    // Code to check order status and update inventory
    // Code to notify customers about their orders
}

Comments Indicating Code Smell

  • Comments that developers leave, indicating a problem that should be addressed.

// TODO: The code is not yet finished.
// Address this ASAP!!

Inconsistent Naming Conventions

  • Inconsistent naming of variables, functions, or classes can make code difficult to understand and lead to confusion.

Unused Code

  • Code that is not being used should be removed to avoid confusion and clutter.

// Any code that is not used by the system:
// int i = 0; (commented out)

Complex Conditionals

  • Complex conditionals that are difficult to read can indicate convoluted logic that should be refactored for clarity.

  • Example:

if ((x > 0 and y > 0) or (x < 0 and y < 0)) {}
// Can be simplified to (assuming no negative values)
if ((x * y) > 0) {}

Excessive Nesting

  • Excessive nesting of loops, conditionals, or functions can make code difficult to read and understand.

Primitive Obsession

  • Overuse of primitive data types can make code difficult to maintain and add new features.

def get_employee_details(name, age, salary):
    return {"name": name, "age": age, "salary": salary}

employee1 = get_employee_details("John", 30, 50000)
# It can be modeled into a class
class Employee:
    def __init__(self, name, age, salary):
        self.name = name
        self.age = age
        self.salary = salary

def get_employee_details(name, age, salary):
    return Employee(name, age, salary)

employee1 = get_employee_details("John", 30, 50000)

Styles of Writing and General Tips

  • Curly Braces: Make the readability of the code easier, match the curly braces to its partner.

    if (score < passing) {
        // some code here
    }
    if (score < passing)
    {
        // some code here
    }
  • Comments:

    • Multi-line comments:

      /*
      This is a multi-
      line comment
      */
    • Single-line comments:

      // This is a single
      // line comment
  • Code Examples: Presents a series of humorous Fibonacci number implementations, varying from a CS 101 student's code to code written by a math Ph.D., to highlight different coding styles and complexities.

  • Comments (cont.):

    • Explain yourself in code.

    • Types: Good comment, Legal comment, clarification comment, warning of consequence, TODO comments

    • Bad comments: Mumbling, redundant, misleading, mandated, journal, noise, scary noise

  • Functions:

    • Functions should only do one thing!

    • Flag arguments in functions are not a good idea!

    • Arguments:

      • Niladic (0 arguments)

      • Monadic (1 argument)

      • Dyadic (2 arguments)

      • Triads (3 arguments)

      • Polyadic (more than 3 arguments)

  • According to Steve McConnell, “careful programmers avoid bundling data more than is logically necessary.”

  • According to Robert Martin:

    • “The first rule of functions is that they should be small; the second rule is that they should be smaller than that. Functions should not be 100 lines long. Functions should hardly ever be 20 lines long.”

Principles and Rules

DRY Rule

  • "Don't Repeat Yourself"

  • Eliminate duplication of code.

WET Rule

  • "Write Everything Twice"

  • Opposite of DRY Rule

KISS Rule

  • “Keep it Simple, Stupid”

  • Ensure the implementation of an algorithm or any piece of solution is done as simply as possible.

Boy Scout Rule

  • "Always leave the campground cleaner than you found it."