Object calisthenics

9 Steps to Better OO Code


Warsaw, 06.07.2016
 

the purpose of this meetinG


Learn how to make our code more:
  1. Readable,
  2. Reusable,
  3. Testable,
  4. Maintainable.

 

Calisthenics

Cal • is • then • ics - /ˌkaləsˈTHeniks/

"Calisthenics are exercises consisting of a variety of gross motor movements; often rhythmical and generally without equipment or apparatus."
Wikipedia                        

object calisthenics

Jeff Bay, "ThoughtWorks Anthology"

but Why bother?

"Code is read more than it is written"

"You need to write code that minimizes the time it would take someone else to understand it - even if that someone else is you."
"Art of Readable Code"                       
Dustin Boswell, Trevor Foucher                       
 
 
 

Rule #1



Only one level of indentation per method
 
 
class Board {
    public String board() {
        StringBuilder buf = new StringBuilder();

        // 0
        for (int i = 0; i < 10; i++) {
            // 1
            for (int j = 0; j < 10; j++) {
                // 2
                buf.append(data[i][j]);
            }
            buf.append("\n");
        }

        return buf.toString();
    }
}
class Board {
    public String board() {
        StringBuilder buf = new StringBuilder();

        collectRows(buf);

        return buf.toString();
    }

    private void collectRows(StringBuilder buf) {
        for (int i = 0; i < 10; i++) {
            collectRow(buf, i);
        }
    }

    private void collectRow(StringBuilder buf, int row) {
        for (int i = 0; i < 10; i++) {
            buf.append(data[row][i]);
        }

        buf.append("\n");
    }
}

Benefits of rule #1

  1. Single Responsibility Principle,
  2. Readability,
  3. Maintainability,
  4. Testability,
  5. Reusability,
  6. Better naming.
 
 
 

Rule #2



Do not use else keyword
public void login(String username, String password) {
    if (userRepository.isValid(username, password)) {
        redirect("homepage");
    } else {
        addFlash("error", "Bad credentials");

        redirect("login");
    }
}
public void login(String username, String password) {
    if (userRepository.isValid(username, password)) {
        return redirect("homepage");
    }

    addFlash("error", "Bad credentials");

    return redirect("login");
}

Benefits of rule #2

  1. Readability,
  2. Clean code,
  3. Avoids code duplication.

Rule #3



Wrap primitive types if it has behaviour

Benefits of rule #3

  1. Encapsulation,
  2. Type hinting (PHP),
  3. Attracts similar behaviour.
 

Rule #4



Only one dot per line
class Location {
    public Piece current;
}

class Piece {
    public String representation;
}

class Board {
    public String boardRepresentation() {
        StringBuilder buf = new StringBuilder();

        for (Location loc : squares()) {
            buf.append(loc.current.representation.substring(0, 1));
        }

        return buf.toString();
    }
}
class Location {
    private Piece current;

    public void addTo(StringBuilder buf) {
        current.addTo(buf);
    }
}
class Piece {
    private String representation;

    public String character() {
        return representation.substring(0, 1);
    }

    public void addTo(StringBuilder buf) {
        buf.append(character());
    }
}
class Board {
    public String boardRepresentation() {
        StringBuilder buf = new StringBuilder();

        for (Location location : squares()) {
            location.addTo(buf);
        }

        return buf.toString();
    }
}

benefits of rule #4


  1. Readability,
  2. Encapsulation,
  3. Easier to debug,
  4. Demeter's law,
  5. Open/Closed Principle.
 

Rule #5



Do not abbreviate

Why abbreviate?

Typing the same word over and over again?

Perhaps your method is used too heavily and you are missing opportunities to remove duplication.

Are method names getting long?

Might be a sign of a misplaced responsibility or a missing class.
 
 

Benefits of rule #5


  1. Clear intentions,
  2. Indicate underlying problems.

Rule #6



Keep your entities small
 

Benefits of rule #6


  1. Single Responsibility Principle,
  2. Objective methods,
  3. Slimmer namespaces.
 

Rule #7



No more than 2 instances variable per class


benefits of rule #7


  1. High cohesion,
  2. Encapsulation,
  3. Fewer dependencies,
  4. Easier to test.

Rule #8



First class collections

Rule #9



Do not use setters/getters
private int score;

public void setScore(int score) {
    this.score = score;
}

public int getScore() {
    return score;
}

// Usage
game.setScore(game.getScore() + ENEMY_DESTROYED_SCORE);
public void addScore(int delta) {
    score += delta;
}

// Usage
game.addScore(ENEMY_DESTROYED_SCORE);

 
 

benefits of rule #9


  1. Open/Closed Principle
 

Catch 'em all!

  1. Only one level of indentation per method,
  2. Do not use else keyword,
  3. Wrap primitive types if it has behavior,
  4. Only one dot per line,
  5. Don’t abbreviate,
  6. Keep your entities small,
  7. No more than two instance variable per class,
  8. First Class Collections,
  9. Do not use accessors
  10. ???
  11. PROFIT!
 

Homework


Create new project up to 1000 lines long, 
and apply presented rules as strictly as possible.

Final thoughts


These are not best practices or even 
guidelines for production code.

Use with caution!

Thank you!

 
 
 

Object Calisthenics

By Paweł Lewtak

Object Calisthenics

9 Steps To Better OOP Code

  • 438