Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Writing Clean Code for Humans

Writing Clean Code for Humans

Have you ever wondered why you constantly have difficulty understanding your code months or years later, or how difficult it is for others to understand your code? Every developer should be able to write clean, easy-to-understand code. My talk will discuss a few bad coding practices we often overlook that can quickly cause problems for you and your team, and how you can avoid them.

Gift Egwuenu

April 20, 2022
Tweet

More Decks by Gift Egwuenu

Other Decks in Programming

Transcript

  1. WHAT'S WRONG WITH THIS CODE? // sending get request to

    Shopify Admin API const x = await Shopify.Utils.loadCurrentSession(req, res); const y = new Shopify.Clients.Rest(x.shop, x.accessToken); const products = await y.get({ path: 'products', });
  2. WHAT'S WRONG WITH THIS CODE? // sending get request to

    Shopify Admin API const x = await Shopify.Utils.loadCurrentSession(req, res); const y = new Shopify.Clients.Rest(x.shop, x.accessToken); const products = await y.get({ path: 'products', });
  3. WHAT'S WRONG WITH THIS CODE? // sending get request to

    Shopify Admin API const x = await Shopify.Utils.loadCurrentSession(req, res); const y = new Shopify.Clients.Rest(x.shop, x.accessToken); const products = await y.get({ path: 'products', });
  4. WHAT'S WRONG WITH THIS CODE? // sending get request to

    Shopify Admin API const x = await Shopify.Utils.loadCurrentSession(req, res); const y = new Shopify.Clients.Rest(x.shop, x.accessToken); const products = await y.get({ path: 'products', });
  5. BETTER EXAMPLE // sending get request to Shopify Admin API

    const session = await Shopify.Utils.loadCurrentSession(req, res); const client = new Shopify.Clients.Rest(session.shop, session.accessToken); const products = await client.get({ path: 'products', });
  6. There are only two hard things in Computer Science: cache

    invalidation and naming things. — Phil Karlton
  7. USE INTENTIONAL- REVEALING NAMES // ❌ this is a bad

    example import { Order } from '@shopify/shopify-api/dist/rest-resources/2022-04/index.js'; const x = await Shopify.Utils.loadCurrentSession(request, response); const y = new Order({session: x }); y.id = 450789469; await y.cancel({});
  8. USE INTENTIONAL- REVEALING NAMES // ✅ this is a good

    example import {Order} from '@shopify/shopify-api/dist/rest-resources/2022-04/index.js'; const current_session = await Shopify.Utils.loadCurrentSession(request, response); const order = new Order({session: current_session}); order.id = 450789469; await order.cancel({});
  9. USE PRONOUCABLE NAMES // ❌ this is a bad example

    const yyyy = new Date('August 19, 1975 23:15:30'); const date1 = yyyy.getDate();
  10. USE PRONOUCABLE NAMES // ✅ this is a good example

    const birthday = new Date('August 19, 1975 23:15:30'); const date = birthday.getDate();
  11. FUNCTION SHOULD DO JUST ONE THING // ❌ this is

    a bad example function getCustomer(customer) { const customerName = prompt("What is your name?"); console.log(`Hello ${customerName}! How are you?`); const customerAddress = prompt("What is your address?"); console.log(`My address is: ${customerAddress}.`); } return getCustomer();
  12. FUNCTION SHOULD DO JUST ONE THING // ❌ this is

    a bad example function getCustomer(customer) { const customerName = prompt("What is your name?"); console.log(`Hello ${customerName}! How are you?`); const customerAddress = prompt("What is your address?"); console.log(`My address is: ${customerAddress}.`); } return getCustomer();
  13. FUNCTION SHOULD DO JUST ONE THING // ✅ this is

    a good example function getCustomerName(customer) { const customerName = prompt("What is your name?"); console.log(`Hello ${customerName}! How are you?`); } function getCustomerAddress(customer) { const customerAddress = prompt("What is your address?"); console.log(`My address is: ${customerAddress}.`); }
  14. NEVER EXPLAIN WHAT THE CODE IS DOING // Load the

    current session to get the `accessToken`. const session = await Shopify.Utils.loadCurrentSession(req, res); // Create a new client for the specified shop. const client = new Shopify.Clients.Rest(session.shop, session.accessToken); // Use `client.get` to request the specified Shopify REST API endpoint, in this case `products`. const products = await client.get({ path: 'products', });
  15. REMOVE COMMENTED CODE const adminApiClient = new Shopify.Clients.Rest( session.shop, session.accessToken,

    ); // const storefrontTokenResponse = await adminApiClient.post({ // path: 'storefront_access_tokens', // type: DataType.JSON, // data: { // storefront_access_token: { // title: 'This is my test access token', // }, // }, // });
  16. AVOID JOURNAL COMMENTS /** * 2022-04-20: Removed call to GraphQL

    Endpoint, will do that later (GE) * 2022-04-01: Improved Code Quality (JP) */ const storefrontAccessToken: string; const session = await Shopify.Utils.loadCurrentSession(req, res); // StorefrontClient takes in the shop url and the Storefront Access Token for that shop. const client = new Shopify.Clients.Storefront( session.shop, storefrontAccessToken, ); });
  17. LEGAL COMMENTS /* @licstart Copyright (©) 2022 CompanyName Available under

    the terms of the GNU/LGPL-3.0 See LICENSE file for more informations. @licend */ const storefrontAccessToken: string; const session = await Shopify.Utils.loadCurrentSession(req, res); const client = new Shopify.Clients.Storefront( session.shop, storefrontAccessToken, ); });
  18. JSDOC COMMENTS /** * Storefront POST API * @constructor *

    @param {object} req - The request object * @param {object} res - The response object */ const storefrontAccessToken: string; const session = await Shopify.Utils.loadCurrentSession(req, res); const client = new Shopify.Clients.Storefront( session.shop, storefrontAccessToken, ); });
  19. TODO COMMENTS // TODO: Implement request to GraphQL endpoint const

    storefrontAccessToken: string; const session = await Shopify.Utils.loadCurrentSession(req, res); const client = new Shopify.Clients.Storefront( session.shop, storefrontAccessToken, ); });
  20. FOLLOW CONSISTENT STYLE // ❌ this is a bad example

    const DAYS_IN_WEEK = 7; const daysInMonth = 30; function getUserData() {} function delete_user_data() {} class user {} class Account {}
  21. FOLLOW CONSISTENT STYLE // ✅ this is a good example

    const DAYS_IN_WEEK = 7; const DAYS_IN_MONTH = 30; function getUserData() {} function deleteUserData() {} class User {} class Account {}
  22. FOLLOW CONSISTENT STYLE // ✅ this is a good example

    const DAYS_IN_WEEK = 7; const DAYS_IN_MONTH = 30; function getUserData() {} function deleteUserData() {} class User {} class Account {}
  23. FOLLOW CONSISTENT STYLE // ✅ this is a good example

    const DAYS_IN_WEEK = 7; const DAYS_IN_MONTH = 30; function getUserData() {} function deleteUserData() {} class User {} class Account {}
  24. LAWS OF TDD ▸ Write production code only to pass

    a failing unit test. ▸ Write no more of a unit test than sufficient to fail (compilation failures are failures).
  25. LAWS OF TDD ▸ Write production code only to pass

    a failing unit test. ▸ Write no more of a unit test than sufficient to fail (compilation failures are failures). ▸ Write no more production code than necessary to pass the one failing unit test.
  26. Good tests should follow the FIRST principle: F = Fast

    i = Isolated R = Repeatable S = Self Validating T = Timely
  27. BAD CODE: ERROR HANDLING WITH TRY, CATCH EXPECTIONS app.post('/webhooks', async

    (req, res) => { try { await Shopify.Webhooks.Registry.process(req, res); } catch (error) { // ❌ this is not sufficient console.log(error); } });
  28. GOOD CODE: ERROR HANDLING WITH TRY, CATCH EXPECTIONS app.post('/webhooks', async

    (req, res) => { try { await Shopify.Webhooks.Registry.process(req, res); } catch (error) { // ✅ this is better console.log(error); notifyUserOfError(error); reportErrortoService(error); } });
  29. HOW YOU CAN TELL YOUR CODE IS CLEAN? ▸ Can

    someone else read this and understand what I wrote?
  30. HOW YOU CAN TELL YOUR CODE IS CLEAN? ▸ Can

    someone else read this and understand what I wrote? ▸ How easy is it going to be to add new features further down the line?
  31. HOW YOU CAN TELL YOUR CODE IS CLEAN? ▸ Can

    someone else read this and understand what I wrote? ▸ How easy is it going to be to add new features further down the line? ▸ Do you constantly break existing functionality when making changes?
  32. BEST PRACTICES FOR WRITING CLEAN CODE ▸ Use meaningful naming

    conventions ▸ Write clean functions ▸ Good code comments
  33. BEST PRACTICES FOR WRITING CLEAN CODE ▸ Use meaningful naming

    conventions ▸ Write clean functions ▸ Good code comments ▸ Format and use a style guide
  34. BEST PRACTICES FOR WRITING CLEAN CODE ▸ Use meaningful naming

    conventions ▸ Write clean functions ▸ Good code comments ▸ Format and use a style guide ▸ Follow TDD principles
  35. BEST PRACTICES FOR WRITING CLEAN CODE ▸ Use meaningful naming

    conventions ▸ Write clean functions ▸ Good code comments ▸ Format and use a style guide ▸ Follow TDD principles ▸ Handle errors correctly
  36. RESOURCES ▸ Clean Code Book - Robert Martin ▸ Code

    Complete - Steve McConnell ▸ Introduction to Clean Code and Software Design Principles
  37. RESOURCES ▸ Clean Code Book - Robert Martin ▸ Code

    Complete - Steve McConnell ▸ Introduction to Clean Code and Software Design Principles ▸ Writing Clean Code for Humans - Cory House