switchon@lavalamp.biz
+27(0) 83 419 4851 / +27(0) 21 036 1165
Application & software development
Get A Quote

    • Home
    • Services
      • Application & software development
      • Outsourced software development
      • Project based resourcing
      • Digital marketing & consulting
      • Graphic design & consulting
      • UI / UX design & consulting
      • Recruitment services
      • Lease an expert
    • About
      • How we work
      • NBConsult Group
      • Partners
      • Lightbox Digital
    • Blog
    • Join us
    • Contact

    • Home
    • Services
      • Application & software development
      • Outsourced software development
      • Project based resourcing
      • Digital marketing & consulting
      • Graphic design & consulting
      • UI / UX design & consulting
      • Recruitment services
      • Lease an expert
    • About
      • How we work
      • NBConsult Group
      • Partners
      • Lightbox Digital
    • Blog
    • Join us
    • Contact

    • Home
    • Services
      • Application & software development
      • Outsourced software development
      • Project based resourcing
      • Digital marketing & consulting
      • Graphic design & consulting
      • UI / UX design & consulting
      • Recruitment services
      • Lease an expert
    • About
      • How we work
      • NBConsult Group
      • Partners
      • Lightbox Digital
    • Blog
    • Join us
    • Contact

    • Home
    • Services
      • Application & software development
      • Outsourced software development
      • Project based resourcing
      • Digital marketing & consulting
      • Graphic design & consulting
      • UI / UX design & consulting
      • Recruitment services
      • Lease an expert
    • About
      • How we work
      • NBConsult Group
      • Partners
      • Lightbox Digital
    • Blog
    • Join us
    • Contact
    git version control
    A Simple And Powerful Git Version Control Workflow
    May 31, 2021
    whats new in tech
    What’s New In Tech?
    Jun 25, 2021

    Clean Code Best Practices

    Categories
    • Software Development
    Tags
    • clean code
    • code
    • coding
    • software development
    code
    code

    Introduction


    In this post I would like to share some principles and concepts that I have learnt, and hopefully this guide can aid you into expanding your programming knowledge and become a better dev from it.

    I think we as Devs often are guilty of writing code that works and is quick to type up, rather than considering writing clearer code thats more focused and easier to read. The guide is not to go through Design Principles and Architecture or to explain programming paradigms such as OOP vs Functional vs Procedural programming but rather these guidelines are merely to offer some knowledge in how you can structure your code to be cleaner for yourself and any team member who comes across your code and has to expand on your developments.

    the following is a summary of what I have learnt in the Udemy Course by

    Maximilian Schwarzmüller - Academind

    Clean Code Course


    Body


    What is Clean Code?

    its not about whether code works or not, its about whether code is easy to read and understand. A vast majority of our time as developers is spent reading and understanding code.so reading and understanding code should be easy.

    Here are some pointers that outline what is "Clean Code"

    • Should be readable and meaningful
    • Should reduce cognitive load
    • Should be concise and "to the point"
    • Should avoid unintuitive names, complex nesting and big code blocks
    • Should follow common best practices and patterns
    • Should be fun to write and to maintain

    You code is like an essay and you are the author, write it such that it's fun and easy to read and understand.


    Key Pain Points

    1. Names
      1. Variables
      2. Functions
      3. Classes
    2. Structure
      1. Code formatting
      2. Good & Bad Comments
    3. Functions/Methods
      1. Length
      2. Parameters
    4. Conditionals & Error Handling
      1. Deep Nesting
      2. Missing Error Handling
    5. Classes & Data Structures
      1. Missing Distinction
      2. Bloated Classes

    Solutions are

    1. Rules and Concepts
    2. Patterns & Principles
    3. Test-Driven Development

    Naming


    Why Good Names Matter

    Names should be meaningful, and should transport what a variable or method/function should do.

    Here is an example of a poorly names piece of code:

    const us = new MainEntity();
    us.process(); if(login){ //... }
    

    as you can see nothing really makes sense from the get go. nothing is straight forward and this code will mean that you will have to dig deeper into each function and variable to understand its meaning. Take a look at an example where we refactor the above into code that is more easy to understand.

    class User { 
    save() {} 
    
    } 
    
    const isLoggedIn = true; 
    
    const user = new User(); 
    user.save(); 
    
    if (isLoggedIn) { // ... }
    

    as you can see, it's the same code, but way easier to read and understand.

    in conclusion to this, well-named "things" allow readers to understand your code without going through it in detail


    1.How to name things correctly


    variable & Constants

    Use nouns or short phrases with adjectives e.g

    const userData = {...} 

    or

    const isValid = ... 

    Functions & Methods

    use verbs or short phrases with adjectives e.g

    sendData();
    inputIsValid();

    Classes

    use nouns or short phrases with nouns

    class User {...}
    
    class RequestBody {...}


    Name Casings


    snake_case camelCase PascalCase kebab-case
    is_valid isValid; SendResponse AdminRole; UserRepository <side-drawer>
    e.g Python, PHP Java, Javascript Python, Java, Javascript e.g HTML
    Variables, functions, methods Variables, functions, methods Classes Custom HTML elementsL



    2. Code Structure, Comments & Formatting


    Bad Comments include the following:

    1. Redudent information
    2. Dividers/Blockers
    3. Misleading information
    4. Commented out code.

    Good Comments include the following:

    1. Legal Information
    2. Explanation which can’t be replaced by good meaning
    3. Warnings
    4. Documentation

    Code Formatting

    Code Formatting improves Readability & Transports Meaning

    There are two areas of formatting to consider

    1. Vertical Formatting
    2. Horizontal Formatting
    Vertical Formatting
    1. Vertical Space Between Lines
    2. Grouping of Code
    Horizontal Formatting
    1. Indentation
    2. Space Between Code

    Functions & Methods


    What makes up a function?

    Calling the function should be readable and working with the function should be easy

    therefore the number and order of arguments matter and the length of the function body matters.


    Minimize the number of parameters

    why? Because the more parameters a function uses the more difficult it becomes to use.

    A function with no parameters is the simplest function to call and read and this should always be the goal when creating a function.

    of course there will be situations where you will need to use parameters and from there obviously 1 parameters is the next best thing to no parameters.

    2 Parameters starts to become more tricky to understand as it requires more information in order to get the function to run, a function with 2 parameters is acceptable but should be used with caution.

    3 Arguments is really difficult to understand and is usually challenging to call and should be avoided if possible. It's usually difficult to determine the order of arguments and that inherently becomes more complex and difficult to understand.

    any function with more than 3 arguments should be avoided at all costs because it's extremely difficult to understand and maintain. there are solutions to handle functions that require so many arguments.


    Refactoring Functions that have multiple params.

    function saveUser(email, password){
        const user = {
            id: Math.random().toString(),
            email:email,
            password: password
        }
        db.insert('users', user);
    }
    
    saveUser('user@test.com' , '123');
    

    This is not terrible code and does make sense when reading it, however it can be refactored to use less parameters. Take the following code as an example where we outsouce the user argument and parse in a single argument to the function.

    function saveUser(user){
        db.insert('users',user)
    }
    

    the above is better because it only takes in one argument for the function to work, and that greatly simplifies the calling of the function. The better solution would be to lift this functionality into a class based approach, such as the following:

    class User{
        constructor(userData){
            this.email = userData.email;
            this.password = userData.password;
            this.id = Math.random().toString();
        }
    
        save(){
            db.insert('users',this);
        }
    }
    
    const user = new User({email: 'test.user.com', password: '123'})
    user.save();
    

    This is much better as its very easy to read and you can immediately see what is expected to get a user object.


    functions should be small and do one thing.

    As developers we often get carried away with writing huge chunks of code and often forget to split our functions into smaller and more meaningful functions.

    in general a function can have code naming and formatting, but a monolithic function that handles multiple things all at once is still considered bad code. It's okay to write more code if it adds readability and clarity to what it is that you are trying to achieve



    Understanding levels of abstraction

    So when it comes to abstraction you have a range of levels.

    1. High Level
    2. Low Levels

    High levels can be thought of as user defined functions e.g

    isEmail(email)
    

    Low Level abstractions is usually language or programme specific low level api and methods.

    e.g

    email.includes('@);

    in High Level operations we don't control how the email is validated - we just want it to be validated. So

    in Low level operations, we control how the email is validated.

    Something else to note is that high level abstractions usually are easy to read - there is no room for interpretation, whereas low level operations might be technically clear but the interpretation must be added by the reader

    Functions should do work that's one level of abstraction below their name

    Okay what does that mean?

    take a look at the example below:

      function emailIsValid(email){
          return email.includes('@');
      };

    as you can tell the name of the function expands/describes the low level implementation of what this function is doing, its important to understand that a function should be clear as to what its purpose is. the function its self is a high level abstraction of the low level code that is within the function, and that makes it easier to understand and interpret.

    take a look at the below and see how one should not use low level abstractions in a high level function.

    function saveUser(email){
      if(email.includes('@')){
        //...
      }
    }

    as you can tell the function name does not really interpret the low level code within the function. Yes it makes sense that function like this should have a step for validation but having the validation directly in this function is not clear and requires some additional thinking as to what is the purpose of the function.

    a function like this should orchestrate all the steps that are required to save a user.


    Try not to mix levels of Abstraction

    take a look at the following:

      if(!email.includes('a')){
        console.log('Invalid email!');
      }else{
        const user = new User(email);
        user.save();
      }

    as you can see we are clearly mixing levels of abstraction here, and this forces the reader to read and understand and interpret each block of code to fully understand each step

    where as the following makes things a lot clearer and the reader only has to read the steps to understand the code.

    if(!isEmail(email)){
      showError('Invalid Email');
    }else{
      saveNewUser(email)
    }

    Keeping functions short

    here are two rules of thumb that can help you identify when to split code or when to merge code.

    take a look at the following:

    user.setAge(21);
    user.setName('Mitchell');

    a rule of thumb

    Extract code that works on the same functionality.

    we can simplify the above to a single function.

      user.update({name: 'Mitchell', age: 21 });

    the second rule of thumb.

    Extract code that requires more interpretation than the surrounding code

    for e.g

    if(!email.includes('@')){...}
      saveNewUser(email);

    then we can easily see that this email.includes check requires more interpretation from our side than having a look at saveNewUser.

    There it's directly obvious what this does and why we're doing this. For email.includes, we have to add the extra meaning of email validation being done here.

    So changing it to this code to the following would bring it all back onto the same level of abstraction and on the same level of required interpretation, you could say.

    if(!isValid(email)){...}
    saveNewUser(email)


    Why Unit tests matter


    Unit Tests matter because it forces you to write slim and focused functions which are easier to test and typically read and understand.


    The next step to mastering writing clean code

    This blog post was really an introduction to understanding clean code and what it really is about. the next step after reading this post is to go deeper into Control Structures, Object and Classes, and to Learn the SOLID principles.

    these topics are quite broad for this post but defiantly comment if you would like to see a follow up post on these topics.

    Contact us


      Related posts:

      laravel livewireLaravel Livewire how to deploy your app/website on herokuHow To Deploy Your App/Website On Heroku dynamic doughnut graph using laravel vue componentDynamic Doughnut Graph Using Laravel Vue Component errors in app insightsUnhandled Promises Sent Through To App Insights In Node JS
      Share
      29
      Mitchell Yuen
      Mitchell Yuen

      Leave a Reply Cancel reply

      Your email address will not be published. Required fields are marked *

      Lava Lamp Lab


      Like technology, a lava lamp constantly changes form, producing new conditions with every passing moment



      lava lamp lab facebook   lava lamp lab twitter   lava lamp lab linkedin   lava lamp lab instgram

      Services


      Application & software development

      Outsourced software development

      Project based resourcing

      Digital marketing & consulting

      Graphic design & consulting

      UI / UX design & consulting

      Contact Us


      +27(0) 83 419 4851

      +27(0) 21 036 1165


      switchon@lavalamp.biz


      Unit 4 Monaco Square,
      14 Church Street,
      Durbanville,
      Cape Town, 7550

      NBConsult Group


      nbconsult
      nbconnect msp
      nbclearning
      river broadband
      designer needed
      © 2023 Lava Lamp Lab (Pty) Ltd | All Rights Reserved | Privacy Policy
      Contact us now

        Application & software development

          Outsourced software development

            Project based resourcing

              Digital marketing & consulting

                Graphic design & consulting

                  UI/UX design & consulting

                    Lease an expert

                      Recruitment services

                        We are using cookies to give you the best experience on our website.

                        You can find out more about which cookies we are using or switch them off in settings.

                        Lava Lamp Lab
                        Powered by  GDPR Cookie Compliance
                        Privacy Overview

                        This website uses cookies so that we can provide you with the best user experience possible. Cookie information is stored in your browser and performs functions such as recognising you when you return to our website and helping our team to understand which sections of the website you find most interesting and useful.

                        Strictly Necessary Cookies

                        Strictly Necessary Cookie should be enabled at all times so that we can save your preferences for cookie settings.

                        If you disable this cookie, we will not be able to save your preferences. This means that every time you visit this website you will need to enable or disable cookies again.

                        3rd Party Cookies

                        This website uses Google Analytics to collect anonymous information such as the number of visitors to the site, and the most popular pages.

                        Keeping this cookie enabled helps us to improve our website.

                        Please enable Strictly Necessary Cookies first so that we can save your preferences!

                        Cookie Policy

                        More information about our Cookie Policy