Friday, 29 September 2017

Book Review: Scrum: a Breathtakingly Brief and Agile Introduction, by Chris Sims and Hillary Louise Johnson

Good, concise, to-the-point introduction and summary of the Scrum way of working for teams and companies. The book covers the Roles (Product Owner, Scrum Master, Team Member), the Artifacts (Product Backlog, Sprint Backlog, Burn Charts etc) and the Sprint Cycle elements (Daily Scrum, Story Time, Sprint Review etc) that make up a Scrum workflow.

Book Summary: Clean Code, by Robert C Martin

An absolute must-read for all software engineers and programmers and especially so if you work with Java or any such programming language. The first half of the book explains the concepts (naming, formatting, testing etc) that make up clean code and lays down the foundation. The second half of the book contains examples of the author working through and cleaning and refactoring code. It all comes together nicely and I've found it to be really impactful in influencing how I think about code.

I've included below a summary of the core messages that I took away from the book.

Foreward
  • Honesty in small things is not a small thing.
  • Cleanliness is next to godliness.
  • Leave the campground cleaner than you found it.
Introduction
  • LeBlanc's law: Later equals never.
  • The fault is not in our stars but in ourselves.
  • A building with broken windows looks like nobody cares about it.
  • One broken window starts the process toward decay.
  • Bad code tries to do too much, it has muddled intent and ambiguity of purpose. Clean code is focused. Each function/class/module exposes a single-minded attitude that remains entirely undistracted, and polluted, by the surrounding details.
  • Readers of our code should perceive us to have been decisive.
  • There is a difference between code that is easy to read and code that is easy to change.
  • When the same thing is done over and over, it's a sign that there is an idea in our mind that is not well represented in the code.
  • Can you imagine working on a project where the code simply got better as time passed? Do you believe that any other option is professional?
Naming
  • You should name a variable using the same care with which you name a first-born child.
  • Choosing good names takes time but saves more than it takes.
  • Don't be afraid to spend time choosing a name.
  • Hunting for a good name often results in a favourable restructuring of the code.
  • If we cannot derive a concise name for a class or function, then it's likely too large. The more ambiguous the class or function name, the more likely it has too many responsibilities.
  • Take care with your names and change them when you find better ones.
  • One difference between a smart programmer and a professional programmer is that the professional understands that clarity is king.
Functions
  • The first rule of functions is that they should be small. The second rule of functions is that they should be smaller than that.
  • Functions should do one thing. They should do it well. They should do it only.
  • You know you are working on clean code when each routine turns out to be pretty much what you expected.
  • The ideal number of arguments for a function is zero. Next comes one, followed closely by two. Three arguments should be avoided where possible.
  • Passing a boolean into a function is a terrible practice. It proclaims that the function does more than one thing: one thing if the flag is true and another if the flag is false.
  • Output arguments should be avoided. If your function must change the state of something, have it change the state of its owning object.
Comments
  • Don't comment bad code – rewrite it.
  • The proper use of comments is to compensate for our failure to express ourself in code.
  • Inaccurate comments are far worse than no comments at all. They delude and mislead.
Formatting
  • When people look under the hood, we want them to be impressed with the neatness, consistency, and attention to detail that they perceive. We want them to be struck by the orderliness. We want them to perceive that professionals have been at work.
  • We want the software to have a consistent style. We don't want it to appear to have been written by a bunch of disagreeing individuals.
Objects
  • There is a reason that we keep our variables private [and not exposed through getters and setters]. We don't want anyone else to depend on them. We want to keep the freedom to change their type or implementation on a whim or an impulse.
  • Law of Demeter: a module should not know about the innards of the objects it manipulates.
Error handling
  • Error handling should be complete. This goes to the discipline of paying attention to details.
Tests
  • Code, without tests, is not clean. No matter how elegant or readable it is.
  • Don't rely on your intuition. Look for every boundary condition and write a test for it.
  • Without a test suite we cannot ensure that changes in one part of our system do not break other parts of the system.
  • If you have tests, you do not fear making changes to the code. Without tests every change is a possible bug.
  • Tests enable change.
  • Having dirty tests is equivalent to, if not worse than, having no tests.
  • The dirtier the tests, the harder they are to change.
  • Test code is just as important as production code. It is not a second-class citizen. It requires thought, design, and care. It must be kept as clean as production code.
  • There are things that you might never do in a production environment that are perfectly fine in a test environment. Usually they involve issues of memory or CPU efficiency. But they never involve issues of cleanliness.
  • The number of asserts in a test ought to be minimised.
  • Minimise the number of asserts per concept and test just one concept per test function.
  • Tests should be F.I.R.S.T: Fast, Independent, Repeatable, Self-Validating, Timely.
  • Testing does not guarantee correctness. However, good testing can minimise risk.
Classes
  • The first rule of classes is that they should be small. The second rule of classes is that they should be smaller than that. 
  • Smaller is the primary rule when it comes to designing classes.
  • We should be able to write a brief description of the class in about 25 words, without using the words "if", "and", "or, or "but".
  • A class or module should have one, and only one, reason to change.
  • Classes should have one responsibility – one reason to change.
  • When classes lose cohesion, split them.
Emergence
  • A system that is comprehensively tested and passes all of its tests all of the time is a testable system.
  • Systems that aren't testable aren't verifiable. A system that cannot be verified should never be deployed.
  • Making our systems testable pushes us toward a design where our classes are small and single purpose.
  • Tight coupling makes it difficult to write tests.

Saturday, 29 April 2017

IntelliJ: Live Template for generating an empty JUnit test method

Here's an IntelliJ / Android Studio Live Template for generating an empty JUnit test method:

@org.junit.Test
public void $testMethodName$() {
    // Given.
    
    // When.
    
    // Then.
}

Set the "Applicability" of the Live Template to be "Java declarations" and set the "Expression" associated to the $testMethodName$ variable to be methodName().

Set the "Abbreviation" and "Description" for the Live Template as you wish and that's it... you're good to go!

Saturday, 10 December 2016

IntelliJ: Live Template for generating a single parameter constructor

Here's an IntelliJ / Android Studio Live Template for generating a constructor that takes in a single parameter and sets that parameter into a class field:

@android.support.annotation.NonNull
private final $dependencyClass$ $dependency$;

private $constructorClass$(@NonNull $dependencyClass$ $dependency$){
    this.$dependency$ = $dependency$;
}

Set the "Applicability" of the Live Template to be "Java declarations" and set the "Expression" associated to each of the variables as follows:
  • $dependencyClass$ -> completeSmart()
  • $dependency$ -> suggestVariableName()
  • $constructorClass$ -> className()
Tick the "Skip if defined" option for the $constructorClass$ variable and set the "Abbreviation" and "Description" for the Live Template as you wish and that's it... you're good to go!

Thursday, 8 December 2016

IntelliJ: Live Template for generating static nested Factory class

If you find yourself having to create a static nested Factory class time and time again then you'll find the following IntelliJ / Android Studio Live Template handy:

public static class Factory {

    @android.support.annotation.NonNull
    private final $dependencyClass$ $dependency$;

    Factory(@NonNull $dependencyClass$ $dependency$){
        this.$dependency$ = $dependency$;
    }

    @NonNull
    public $createdClass$ create(){
        return new $createdClass$($dependency$);
    }
}

Set the "Applicability" of the Live Template to be "Java declarations" and set the "Expression" associated to each of the variables as follows:
  • $dependencyClass$ -> completeSmart()
  • $dependency$ -> suggestVariableName()
  • $createdClass$ -> className()
Tick the "Skip if defined" option for the $createdClass$ variable and set the "Abbreviation" and "Description" for the Live Template as you wish and that's it... you're good to go!

Monday, 2 May 2016

Quran SDK (library) for Android

I've put together a couple of Android apps in my spare time the last few years which make use of verses of the Quran (Hifdh Tracker and Hifdh Tester). I'm in the process of making the code for these apps entirely open source. As a first step I've just extracted the database and the helper methods for accessing verses of the Quran out of the apps and into an Android library of its own. You can find the code repository for the library here. The README in the repository explains how to incorporate and make use of the library in your own apps.

Thursday, 31 December 2015

Bash - basic script for requesting input from the user

As mentioned in this post, my know-how of Bash scripting is pretty nil so I've been skimming through this guide the last few days to get to grips with the basic concepts. I've put together this basic script as a reminder to myself for future reference of how to request and parse input from the user:

#!/bin/bash

echo "Enter the word that you'd like to add to the dictionary and then press [Enter]."

read WORD

PATH_DICTIONARY="/Users/adil/Downloads/MyDictionary.txt"
COUNT=`grep -c "^$WORD$" $PATH_DICTIONARY`

if [ $COUNT -gt 0 ]
then echo "Word is already contained in the dictionary."; exit;
fi

echo "\$COUNT = $COUNT"

echo "Adding $WORD to the dictionary..."

echo "$WORD" >> $PATH_DICTIONARY

echo "Done"