Successfully reported this slideshow.

How to write good quality code



1 of 50
1 of 50

More Related Content

Related Books

Free with a 14 day trial from Scribd

See all

How to write good quality code

  1. 1. Code Quality A brief introduction to writing code that is scalable, shareable and usable. Wednesday, 18th May 2016
  2. 2. Hayden Bleasel Product Designer, Entrepreneur & Full-Stack Developer. Previously at Zookal, Sumry and Palantir. @haydenbleasel on Twitter, GitHub and pretty much everywhere else. Nice to meet you.
  3. 3. What languages do you write and how do you ensure code quality? Quick Question
  4. 4. • Bad code: use once, copied from StackOverflow, thrown away after or used to hotfix a bug • Good code: used multiple times over several projects, maybe a small plugin • Great code: well-thought-out, up to date, unit tested and maybe even open-sourced and built by the community • We need to measure and enforce quality code. What is “Quality Code”?
  5. 5. • Clear and understandable design and implementation. • Well defined interfaces. • Ease of build and use. • Ease of extensibility. • Minimum extra dependencies. • Tests and examples. • Great documentation or self-explaining code. • Up to date means to contact the developer. Goals of Quality Code
  6. 6. • European Space Agency took 10 years and $8 billion dollars to develop Ariane 5 (heavy lift launch rocket). • On June 4, 1996, it took its first voyage with $500 million cargo. In 40 seconds its inertial reference system failed. • 64-bit floating point number representing the horizontal velocity of the rocket was converted into 16-bit signed integer — conversion failed because of overflow. Why bother with quality?
  7. 7. • Finding, fixing problem in production is 100 times more expensive than during requirements / design phase. • 40-50% of effort on projects is on avoidable rework. • ~80% of avoidable rework comes from 20% of defects. • ~80% of defects come from 20% of modules; about half the modules are defect free. • ~90% of downtime comes from at most 10% of defects. • Peer reviews catch 60% of defects. • Perspective-based reviews catch 35% more defects than nondirected reviews. • Disciplined personal practices can reduce defect introduction rates by up to 75%. • ~40-50% of user programs have nontrivial defects. But seriously, why bother?
  8. 8. • Nobody has time to check their code, we’re all busy trying to make amazing things. • You need 2 things: A. To know how to write good code (you think you do but you really don’t). B. To start using an array of tools and workflow to your advantage. But I don’t have time to check code!
  9. 9. • Not really. The QA is meant to go over your output and look for bugs in runtime and edge cases, not to browse your junk code and make incremental improvements. • The only thing that does is gives the QA a reason to yell at you about writing janky code and you’ll go back to the drawing board (that, or more likely it’ll leak into production and hilarity ensues). Isn’t this the job of a QA?
  10. 10. This is basically a giant to-do list for when you go home, things you can add to your product, startup or app. Practical Implementation
  11. 11. Bill Gates Measuring programming progress by lines of code is like measuring aircraft building progress by weight.
  12. 12. • Writing code with style • Keeping code in check • Making code less confusing Overview • Managing dependencies • Git and GitHub • Automation and Testing
  13. 13. 001. Writing code with style
  14. 14. • Don’t give variables cryptic names e.g. Meaningful Variable Names 001. Writing code with style x1 = 60; x2 = 24; x12 = x1 * x2; • They don’t save space - you can compress the output using a minifier. Might as well just use: minutesPerHour = 60; hoursPerDay = 24; minutesPerDay = minutesPerHour * hoursPerDay;
  15. 15. • This doesn’t lead to scalable code: Using Constants 001. Writing code with style coffee = makeCoffee(2) • What does 2 mean? What does this function even accept? We can introduce constants here: SIZES = { small: 1, large: 2 }; coffee = makeCoffee(SIZES.large) • We generally use uppercase for constants.
  16. 16. • This function utilises it’s purpose stringently: Flexible functions 001. Writing code with style makeGrid = function (width) { for (var i = 0; i < 12; i++) { makeColumn(12 / width, 30); } } • We can make this a bit more flexible: makeGrid = function (width, columns, gutter) { for (var i = 0; i < columns; i++) { makeColumn(columns / width, gutter); } } makeGrid(1170) makeGrid(1170, 12, 30)
  17. 17. • It’s pretty simple stuff, just go through all your code and find thing to improve or fix. • Look for runtime errors (overflows, type checking, overwriting variables, memory leaks, etc). • Look for syntax errors (missing a bracket or semicolon, using 1 ampersand instead of 2) • Look for logic errors (passing in the wrong number, calling the wrong function). Code Analysis 001. Writing code with style
  18. 18. • There are two pretty fundamental things you should avoid when writing large projects (especially for open-source): • Black boxes: Functions where parameters go into, pure magic happens and an output comes out, but we have no idea how it works. • TODOs and Hacky Workarounds: Avoid them. However, if you’ve got hacks or unfinished code, document them somewhere outsite the codebase, like GitHub issues. Avoid Black Boxes and Hacks 001. Writing code with style
  19. 19. • More lines of code typically means less code quality. In each file or function, pick one thing and do it really well, a bit like running a startup. • Repeated lines of code or code that looks incredibly similar in terms of structure and purpose can be rewritten as a function. • Seperate your code out into different files. Make sure each file handles a small part of your app. Refactoring and LOC 001. Writing code with style
  20. 20. • If your linter, terminal or whatever throws a warning, don’t ignore it. • Warnings can outline hidden problems that you’ll run into severely later on. • Use the compiler or linter to treat warnings as errors and you’ll be writing amazing code. • If absolutely necessary (legacy code or something), you can suppress warnings. Treat Warnings as Errors 001. Writing code with style
  21. 21. • Some languages, like Javascript and Perl, have a Strict mode that you can enable. • It makes several changes to normal language semantics. • In JavaScript for example, Strict Mode: • Eliminates some silent errors by changing them to throw errors. • Fixes mistakes that make it difficult for JavaScript engines to perform optimisations: strict mode code can sometimes be made to run faster than identical code that's not strict mode. • Prohibits some syntax likely to be defined in future versions of ECMAScript. Strict Mode 001. Writing code with style
  22. 22. 002. Keeping code in check
  23. 23. • A giant report documenting how you and your collaborators should write code on a particular project. • Google has a massive one covering every language they use: https:// • Useful for when you’re running a company or agency where heaps of people are touching the same code. Style Guides 002. Keeping code in check
  24. 24. • Everything we’ve just discussed - that’s a lot of work. Checking, refactoring, rewriting… • Wouldn’t it be better if the code just checked itself? (before it wrecked itself) • Welcome to the wonderful world of rules. You want your codebase to have rules, such as “make sure every file ends with a newline” and “make sure I use anonymous function callbacks all the time”. The possibilities are endless. Automagical code checking 002. Keeping code in check
  25. 25. • Check it out at http:// • Comes as a plugin for almost every text editor and IDE imaginable. • Define extension-based rules like newlines, charsets and indenting. • Runs and fixes on file save. .editorconfig 002. Keeping code in check root = true [*] end_of_line = lf insert_final_newline = true charset = utf-8 indent_style = space indent_size = 4 [*.json] indent_size = 2
  26. 26. • My absolute favourite part of this topic on code quality. • Linters are absolutely amazing and indispensable. • They check your code as you’re writing it. • They literally enforce your style on everyone else. Linting 002. Keeping code in check
  27. 27. • Some languages, like Javascript, have lots of linters to choose from: JSLint, ESLint, JSHint, etc. All of these can be configured, but the default options and extensibility varies. • ESLint is the one shown in these examples. It’s the newest, most extensible linter for Javascript. • You can most linters via CLI, automation module (Gulp or Grunt) and text editor plugin. Choosing a Linter 002. Keeping code in check
  28. 28. "comma-dangle": [2, "never"], "no-cond-assign": [2, "always"], "no-console": 0, "no-constant-condition": 2, "no-control-regex": 2, "no-debugger": 2, "no-dupe-args": 2, "no-dupe-keys": 2, "no-duplicate-case": 2, "no-empty-character-class": 2, "no-empty": 2, Linter Configuration 002. Keeping code in check • Configuring your linter is a tedious process. My .eslintrc is 350 lines long:
  29. 29. How I use my linter 002. Keeping code in check brew cask install atom apm install linter linter-eslint npm install -g eslint • Getting a Linter set up is mad easy. Just install the module and plugins: • That’s it! Just start writing code and save!
  30. 30. 002. Keeping code in check
  31. 31. • Text editors can massively affect code quality, from default intent style to external plugins. • I use Atom, a text editor by GitHub. It comes with an inbuilt package manager. • Packages like linter (+eslint), atom-beautify and editorconfig address things we’ve talked about. Text Editors and Plugins 002. Keeping code in check
  32. 32. 003. Making code less confusing
  33. 33. • Coupling determines how much one component of your code knows about the inner workings of another. We want to aim for LOW coupling. • Ex: iPods are a good example of tight coupling: once the battery dies you might as well buy a new iPod because the battery is soldered fixed and won’t come loose, thus making replacing very expensive. A loosely coupled player would allow effortlessly changing the battery. Coupling 003. Making code less confusing
  34. 34. • Cohesion refers to the extent that a component of your code is focused only on what it should be doing. We want to aim for HIGH cohesion. Cohesion 003. Making code less confusing function main (a, b) { var x = (a * b) / 3; var body = $(‘body’); body.appendChild(x); } main(1,2); function multiply (a, b) { return (a * b) / 3; } function append (number) { var body = $(‘body’); body.appendChild(number); } var number = multiply(1,2); append(number);
  35. 35. • There are two main ways to minimise the complexity of your code. Neither should be your ultimatum, but rather a great referencing guide: 1. Pretty simple: just minimise the number of parameters, depth (nesting) and statements per function 2. Run a cyclomatic complexity test. It calculates the overall intricacy of a function and to give a score that reflects it’s complexity. Lower is better. Complexity 003. Making code less confusing
  36. 36. 004. Managing dependencies
  37. 37. • A common pitfall that results in loss of code quality, even in large organisations, is poor dependency management. • Vendor code is downloaded, chucked in a random folder and modified to the core if it doesn’t work the way you want it to. • This results in all sorts of bugs and creates a generally crap work environment for the developer. Dependency Management 004. Managing dependencies
  38. 38. • Bower is a package management system developed by Twitter. • Bower is used to download and manage front-end development packages like jQuery and Bootstrap. • For example: Bower 004. Managing dependencies bower install jquery --save
  39. 39. • Server-side applications also have dependency management, except much better. • Node.js has NPM, Ruby has Bundler and PHP has Composer. There are plenty of dependency management tools out there for any language. • Rather than messing around with files and versions, just get the latest version of Request with: NPM / Bundler / Composer 004. Managing dependencies npm install request --save-dev
  40. 40. • If you’re not using a dependency manager but still want to maintain the integrity and separation of your codebase from third-party components, CDNJS is a good option. • Again, front-end components. Doesn’t have everything but should have 99% of what you need. • Just throw in a script tag like: CDNJS 004. Managing dependencies <script src=“ 3.0.0-beta1/jquery.min.js"></script>
  41. 41. 005. Git and GitHub
  42. 42. • You should kinda know this already. Git tracks version history so you can see what you’ve done, revert changes and blame mistakes on other people. • Remember to check in your code in small batches, frequently. Reverting massive amounts of unrelated code is a nightmare plus it helps avoid merge conflicts. • Version control is also helpful for semver integrity. Version Control 005. Git and GitHub
  43. 43. • GitHub is the best platform ever for developers. • Use Issues to track your TODOs, hacky workarounds, suggestions from others, etc. Keep the discussion out of your codebase. • Use PRs to filter external changes to your code. PRs allow for Code Reviews where you can go through every change in the diff and add comments. Issues and PRs 005. Git and GitHub
  44. 44. • Can happen in a variety of ways, but likely when you gather all the homies together and start reviewing code that you’ve written or that’s in your codebase. • Great way to pick up and debate really small things that might lead to a significant improvement in performance, or maybe just be really pedantic. • Theoretically, you’re meant to be positive i.e. instead of “that’s lousy long method” say, “why don’t you split that method…” but TBH most of us are savages. Code Reviews 005. Git and GitHub
  45. 45. 006. Automation and Testing
  46. 46. • The original task-runner. • Their architectural concept sucks (pickup and put-down) but it’s pretty widely used. • Stop writing production code in source, focus on quality of source code and let your automation handle the rest. Grunt 006. Automation and Testing
  47. 47. • Best task runner available - unix streaming ideology inside the JS ecosystem. • Set up a bunch of tasks and send files through the pipeline (stream) without touching the file system. • Compile languages, remove debug code, whatever. Gulp 006. Automation and Testing
  48. 48. • Write a script to test your app. Can be as simple as “npm start” which just runs the app. • Will automatically run this every time you push to GitHub. • Also tests GitHub PRs - test new code before you merge. Travis CI 006. Automation and Testing
  49. 49. • So you’ve written unit tests for your code, but how much have you written in the scheme of things? • JS has Mocha, Chai, Istanbul and other libraries to handle this sort of things. • It’s called test coverage - TL;DR it will give you a report on how much of your codebase is covered by unit tests. Most of them compute statement, line, function and branch coverage with module loader hooks. Coverage 006. Automation and Testing
  50. 50. Go forth and stop writing bad code. That’s everything