14. Object Calisthenics
So, here’s an exercise that can help
you to internalize principles of good
object-oriented design and actually
use them in real life.
Jeff Bay
15. 1. Only one level of indentation per method
class Board {
public String board() {
$buf = new StringBuilder();
// 0
for ($i = 0; $i < 10; $i++) {
// 1
for ($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");
}
}
Extract method
https://refactoring.com/catalog/extractMethod.html
16. 2. Don’t use ELSE keyword
function login($username, $password)
{
if ($this->isValid($username, $password)) {
$this->redirect("homepage");
} else {
$this->addFlash("error", "Bad credentials");
$this->redirect("login");
}
}
function login($username, $password) {
if ($this->isValid($username, $password)) {
return $this->redirect("homepage");
}
$this->addFlash("error", "Bad credentials");
return $this->redirect("login");
}
function login($username, $password) {
$redirectRoute = "homepage";
if (!$this->isValid($username, $password)) {
$this->addFlash("error", "Bad credentials");
$redirectRoute = "login";
}
$this->redirect($redirectRoute);
}
Early return
Variable
17. 3. Wrap all primitives and strings
You simply have to encapsulate all the
primitives within objects.
If the variable of primitive type has a
behavior, it MUST be encapsulated.
http://wiki.c2.com/?PrimitiveObsession
18. 4. First class collections
Any class that contains a collection
should contain no other member
variables.
19. 5. One dot per line
You should not chain method calls.
Law of Demeter
Only talk to your immediate friends,
and don’t talk to strangers.
20. 6. Don’t abbreviate
Why Do You Want To Abbreviate?
Write the same name over and over
again?
Method name too long?
https://williamdurand.fr/2012/01/24/designing-a-software-by-naming-things/
21. 7. Keep all entities small
No class over 50 lines and no package
over 10 files.
23. 8. No classes with more than two instance
variables
Two kinds of classes, those that maintain
the state of a single instance variable,
and those that coordinate two separate
variables. Two is an arbitrary choice that
forces you to decouple your classes a lot.
24. 9. No getters/setters/properties
class Game
{
private $score;
public function setScore($score)
{
$this->score = $score;
}
public function getScore()
{
return $this->score;
}
}
// Usage
$game = new Game();
$game->setScore(
$game->getScore() + ENEMY_DESTROYED_SCORE
);
// Game
public function addScore($delta)
{
$this->score += $delta;
}
// Usage
$game->addScore(ENEMY_DESTROYED_SCORE);
Tell, Don't Ask
25. Try them in your spare time, by
refactoring your Open Source projects for
instance. I think it is just a matter of
practice. Some rules are easy to follow,
and may help you.