SlideShare a Scribd company logo
Writing better
code with
Object Calisthenics
Lucas Arruda
lucas@ciandt.com
github.com/larruda
Adapted from Jeff Bay’s paper from
“The ThoughtWorks Anthology”
and Guilherme Blanco’s presentation.
Calis...what?!
1st CI&T Lightning Talks: Writing better code with Object Calisthenics
7 code qualities
cohesion
loose coupling
no redundancy
encapsulation
testability
readability
focus
9
rules of thumb
1. One level of indentation per method
class Board {
...
String board() {
StringBuffer buf = new StringBuffer();
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++)
buf.append(data[i][j]);
buf.append(“n”);
}
return buf.toString();
}
}
1. One level of indentation per method
class Board {
...
String Board() {
StringBuffer buf = new StringBuffer();
collectRows(buf);
return buf.toString();
}
void collectRows(StringBuffer buf) {
for (int i = 0; i < 10; i++)
collectRow(buf, i);
}
void collectRow(StringBuffer buf, int row) {
for (int i = 0; i < 10; i++)
Buf.append(data[row][i]);
buf.append(“n”);
}
}
1. One level of indentation per method
public function validateForm($filters='', $validators='', $options='')
{
$data = $_POST;
$input = new Zend_Filter_Input($filters, $validators, $data);
$input->setDefaultEscapeFilter(new Zend_Filter_StringTrim());
if ($input->hasInvalid() || $input->hasMissing()) {
foreach ($input->getMessages() as $field => $messageList) {
foreach ($messageList as $message) {
if (strpos($message, "empty")) {
throw new Tss_FormException(
"The field {$field} cannot be empty!",
3, 'javascript:history.back();'
);
} else {
throw new Tss_FormException(
"{$message}", 3, 'javascript:history.back();'
);
}
}
}
}
return $input;
}
1. One level of indentation per method
public function validateForm($filters='', $validators='', $options='')
{
$data = $_POST;
$input = new Zend_Filter_Input($filters, $validators, $data);
$input->setDefaultEscapeFilter(new Zend_Filter_StringTrim());
if ( ! ($input->hasInvalid() || $input->hasMissing())) {
return $input;
}
foreach ($input->getMessages() as $field => $messageList) {
foreach ($messageList as $message) {
if (strpos($message, "empty")) {
throw new Tss_FormException(
"The field {$field} cannot be empty!",
3, 'javascript:history.back();'
);
} else {
throw new Tss_FormException(
"{$message}", 3, 'javascript:history.back();'
);
}
}
}
}
1. One level of indentation per method
public function validateForm($filters='', $validators='', ...
{
$data = $_POST;
$input = new Zend_Filter_Input ($filters, $validators, $data);
$input->setDefaultEscapeFilter( new Zend_Filter_StringTrim ());
if ( ! ($input->hasInvalid() || $input->hasMissing())) {
return $input;
}
foreach ($input->getMessages() as $field => $messageList) {
foreach ($messageList as $message) {
$errorMessage = (strpos($message, "empty") === false)
? "The field {$field} cannot be empty!"
: "{$message}";
throw new Tss_FormException (
$errorMessage, 3, 'javascript:history.back();'
);
}
}
}
1. One level of indentation per method
public function validateForm($filters='', $validators='', ...
{
$data = $_POST;
$input = new Zend_Filter_Input ($filters, $validators, $data);
$input->setDefaultEscapeFilter( new Zend_Filter_StringTrim ());
if ( ! ($input->hasInvalid() || $input->hasMissing())) {
return $input;
}
foreach ($input->getMessages() as $field => $messageList) {
$messageKey = key($message);
$message = $message[$messageKey];
$errorMessage = (strpos($message, "empty") === false)
? "The field {$field} cannot be empty!"
: "{$message}";
throw new Tss_FormException (
$errorMessage, 3, 'javascript:history.back();'
);
}
}
2. Don’t use the ELSE keyword
if (status == DONE) {
doSomething();
} else {
…
}
YOU
MUST BE
JOKING!!!
2. Don’t use the ELSE keyword
class Board {
...
String board(StringBuffer buf) {
if (buf.length()) {
return buf.toString();
}
else {
collectRows(buf);
return buf.toString();
}
}
...
}
2. Don’t use the ELSE keyword
class Board {
...
String board(StringBuffer buf) {
if (!buf.length()) {
collectRows(buf);
}
return buf.toString();
}
...
}
2. Don’t use the ELSE keyword
function login() {
$login = $this->input->post('email', true);
$password = $this->input->post('password', true);
$reference = $this->input->post('reference', true);
if ($this->clients_model->login($login, $password)) {
redirect( $reference);
} else {
$this->session->set_flashdata(
'error' , 'User or password invalid.'
);
$this->session->set_flashdata( 'reference', $reference);
redirect( 'clients');
}
}
2. Don’t use the ELSE keyword
function login() {
$login = $this->input->post('email', true);
$password = $this->input->post('password', true);
$reference = $this->input->post('reference', true);
if (!$this->clients_model->login($login, $password)) {
$this->session->set_flashdata(
'error' , 'User or password invalid.'
);
$this->session->set_flashdata( 'reference', $reference);
$reference = 'clients';
}
redirect($reference);
}
3. Wrap all primitives and Strings
If the primitive type has a behavior it
should be encapsulated
3. Wrap all primitives and Strings
class UIComponent
{
// ...
public function repaint($animate = true)
{
// …
}
// ...
$component->repaint(false);
}
3. Wrap all primitives and Strings
class UIComponent
{
// ...
public function repaint(Animate $animate)
{
// ...
}
}
class Animate
{
public $animate;
public function __construct($animate = true)
{
$this->animate = $animate;
}
}
// ...
$component->repaint(new Animate(false));
4. First class collections
Any class that contains a collection/array
should not contain any other member
variables
Java Collections follow this rule
4. First class collections
Transversable
Countable
Iterator
Filtering
Mapping
Combining
5. One dot/arrow per line
Sign of misplaced responsibilities
The Law of Demeter
“Only talk to your friends”
5. One dot/arrow per line
class Board {
...
class Piece {
...
String representation;
}
class Location {
...
Piece current;
}
String boardRepresentation () {
StringBuffer buf = new StringBuffer();
for (Location l: squares())
buf .append(l.current.representation .substring(0,
1));
return buf.toString();
}
}
5. One dot/arrow per line
class Board {
...
class Piece {
...
private String representation;
String character() {
return representation.substring(0, 1);
}
void addTo(StringBuffer buf) {
buf.append(character());
}
}
class Location {
...
private Piece current;
void addTo(StringBuffer buf) {
current.addTo(buf);
}
}
String boardRepresentation() {
StringBuffer buf = new StringBuffer();
for (Location l: squares())
l.addTo(buf);
return buf.toString();
}
}
6. Don’t abbreviate
Are you writing the same name repeatedly?
method being used multiple times
sign of code duplication
Is the method name too long?
class with multiple responsibilities
missing additional class
redundancy
7. Keep all entities small
Java
No class over 50 lines
No packages over 10 files
PHP
No class over 100 lines
No packages over 15 files
Packages, like classes, should be
cohesive and have a purpose
8. No classes with more than two/five instance variables
Improve cohesion
Split on more entities
9. No getters/setters/properties
Improve encapsulation
“Tell, don’t ask”
Q&A
ciandt.com
http://www.cs.helsinki.fi/u/luontola/tdd-2009/ext/ObjectCalisthenics.pdf
http://www.slideshare.net/guilhermeblanco/object-calisthenics-applied-to-php
https://www.youtube.com/watch?v=ftBUHrxfOcc
THANKS
FOR
BEING
HERE!
ciandt.com
lunascar@gmail.com
@lunascarruda
google.com/+LucasArruda
fb.com/lucasnarruda
linkedin.com/in/larruda
github.com/larruda
coderbits.com/larruda
drupal.org/user/1009514

More Related Content

What's hot (20)

PDF
Design Patterns in PHP5
Wildan Maulana
 
PDF
ECMAScript 6 and beyond
Francis Johny
 
PDF
Dependency Injection IPC 201
Fabien Potencier
 
PDF
Introduction to Python
UC San Diego
 
PDF
PHP Language Trivia
Nikita Popov
 
PDF
PYTHON-Chapter 3-Classes and Object-oriented Programming: MAULIK BORSANIYA
Maulik Borsaniya
 
PDF
The Zen of Lithium
Nate Abele
 
PPTX
PHP PPT FILE
AbhishekSharma2958
 
ZIP
Object Oriented PHP5
Jason Austin
 
PDF
Dependency injection - phpday 2010
Fabien Potencier
 
PDF
Python programming : Inheritance and polymorphism
Emertxe Information Technologies Pvt Ltd
 
PDF
Symfony2 - WebExpo 2010
Fabien Potencier
 
PDF
Zend Certification Preparation Tutorial
Lorna Mitchell
 
PPTX
Python: Basic Inheritance
Damian T. Gordon
 
PDF
Creating Domain Specific Languages in Python
Siddhi
 
DOCX
PERL for QA - Important Commands and applications
Sunil Kumar Gunasekaran
 
PDF
Dependency injection in PHP 5.3/5.4
Fabien Potencier
 
PDF
Php unit the-mostunknownparts
Bastian Feder
 
PDF
Functions in PHP
Vineet Kumar Saini
 
PDF
Dependency Injection with PHP and PHP 5.3
Fabien Potencier
 
Design Patterns in PHP5
Wildan Maulana
 
ECMAScript 6 and beyond
Francis Johny
 
Dependency Injection IPC 201
Fabien Potencier
 
Introduction to Python
UC San Diego
 
PHP Language Trivia
Nikita Popov
 
PYTHON-Chapter 3-Classes and Object-oriented Programming: MAULIK BORSANIYA
Maulik Borsaniya
 
The Zen of Lithium
Nate Abele
 
PHP PPT FILE
AbhishekSharma2958
 
Object Oriented PHP5
Jason Austin
 
Dependency injection - phpday 2010
Fabien Potencier
 
Python programming : Inheritance and polymorphism
Emertxe Information Technologies Pvt Ltd
 
Symfony2 - WebExpo 2010
Fabien Potencier
 
Zend Certification Preparation Tutorial
Lorna Mitchell
 
Python: Basic Inheritance
Damian T. Gordon
 
Creating Domain Specific Languages in Python
Siddhi
 
PERL for QA - Important Commands and applications
Sunil Kumar Gunasekaran
 
Dependency injection in PHP 5.3/5.4
Fabien Potencier
 
Php unit the-mostunknownparts
Bastian Feder
 
Functions in PHP
Vineet Kumar Saini
 
Dependency Injection with PHP and PHP 5.3
Fabien Potencier
 

Viewers also liked (13)

PPTX
Bastiar
tiar1
 
DOCX
1
tiar1
 
DOCX
BASTIAR LISTENING 10
tiar1
 
PDF
Using natural remedies to treat chronic symptoms
OptimalWellnessLabs
 
PDF
What to know about quality of fish oil and parent oil as natrual home remedy
OptimalWellnessLabs
 
PPTX
BASTIAR go
tiar1
 
PDF
MKT531 Corporate Branding Gavin Teggart
Gavin Teggart
 
PPTX
This Is Why We Can't Have Nice Things
morganhousel
 
RTF
Bab vi bastiar
tiar1
 
PPTX
Pp. dewi ariani bab 6
dewiarianiaja
 
PPTX
Pp picture halloween
dewiarianiaja
 
PDF
Selling the Open-Source Philosophy - DrupalCon Latin America
Lucas Arruda
 
Bastiar
tiar1
 
BASTIAR LISTENING 10
tiar1
 
Using natural remedies to treat chronic symptoms
OptimalWellnessLabs
 
What to know about quality of fish oil and parent oil as natrual home remedy
OptimalWellnessLabs
 
BASTIAR go
tiar1
 
MKT531 Corporate Branding Gavin Teggart
Gavin Teggart
 
This Is Why We Can't Have Nice Things
morganhousel
 
Bab vi bastiar
tiar1
 
Pp. dewi ariani bab 6
dewiarianiaja
 
Pp picture halloween
dewiarianiaja
 
Selling the Open-Source Philosophy - DrupalCon Latin America
Lucas Arruda
 
Ad

Similar to 1st CI&T Lightning Talks: Writing better code with Object Calisthenics (20)

KEY
Object Calisthenics Applied to PHP
Guilherme Blanco
 
PDF
PHP for Adults: Clean Code and Object Calisthenics
Guilherme Blanco
 
PPSX
What's New In C# 7
Paulo Morgado
 
PPT
Scala presentation by Aleksandar Prokopec
Loïc Descotte
 
KEY
Symfony2 Building on Alpha / Beta technology
Daniel Knell
 
ODP
Introduction to Scala
Lorenzo Dematté
 
KEY
ddd+scala
潤一 加藤
 
PDF
Elm: give it a try
Eugene Zharkov
 
PDF
Introduction to Scala
Aleksandar Prokopec
 
PDF
Your code sucks, let's fix it - DPC UnCon
Rafael Dohms
 
PPT
JBUG 11 - Scala For Java Programmers
Tikal Knowledge
 
PPTX
Introduction to kotlin
Shaul Rosenzwieg
 
PDF
Imugi: Compiler made with Python
Han Lee
 
PDF
PhpUnit - The most unknown Parts
Bastian Feder
 
PDF
Leveraging Symfony2 Forms
Bernhard Schussek
 
PDF
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
Hiroshi Ono
 
PDF
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
Hiroshi Ono
 
PDF
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
Hiroshi Ono
 
PDF
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
Hiroshi Ono
 
PDF
Lezione03
robynho86
 
Object Calisthenics Applied to PHP
Guilherme Blanco
 
PHP for Adults: Clean Code and Object Calisthenics
Guilherme Blanco
 
What's New In C# 7
Paulo Morgado
 
Scala presentation by Aleksandar Prokopec
Loïc Descotte
 
Symfony2 Building on Alpha / Beta technology
Daniel Knell
 
Introduction to Scala
Lorenzo Dematté
 
ddd+scala
潤一 加藤
 
Elm: give it a try
Eugene Zharkov
 
Introduction to Scala
Aleksandar Prokopec
 
Your code sucks, let's fix it - DPC UnCon
Rafael Dohms
 
JBUG 11 - Scala For Java Programmers
Tikal Knowledge
 
Introduction to kotlin
Shaul Rosenzwieg
 
Imugi: Compiler made with Python
Han Lee
 
PhpUnit - The most unknown Parts
Bastian Feder
 
Leveraging Symfony2 Forms
Bernhard Schussek
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
Hiroshi Ono
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
Hiroshi Ono
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
Hiroshi Ono
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
Hiroshi Ono
 
Lezione03
robynho86
 
Ad

More from Lucas Arruda (8)

PDF
Serverless no Google Cloud
Lucas Arruda
 
PDF
How to build an ETL pipeline with Apache Beam on Google Cloud Dataflow
Lucas Arruda
 
PDF
Escalando PHP e Drupal: performance ao infinito e além! - DrupalCamp SP 2015
Lucas Arruda
 
PDF
InterConPHP 2014 - Scaling PHP
Lucas Arruda
 
PDF
Drupal Day SP 2014 - Virtualize seu Ambiente e Seja Produtivo!
Lucas Arruda
 
PDF
QCon SP - ShortTalk - Virtualização e Provisionamento de Ambientes com Vagr...
Lucas Arruda
 
PDF
PHP Conference Brasil 2013 - Virtualização e Provisionamento de Ambientes c...
Lucas Arruda
 
PDF
TDC2013 - PHP - Virtualização e Provisionamento de Ambientes com Vagrant e ...
Lucas Arruda
 
Serverless no Google Cloud
Lucas Arruda
 
How to build an ETL pipeline with Apache Beam on Google Cloud Dataflow
Lucas Arruda
 
Escalando PHP e Drupal: performance ao infinito e além! - DrupalCamp SP 2015
Lucas Arruda
 
InterConPHP 2014 - Scaling PHP
Lucas Arruda
 
Drupal Day SP 2014 - Virtualize seu Ambiente e Seja Produtivo!
Lucas Arruda
 
QCon SP - ShortTalk - Virtualização e Provisionamento de Ambientes com Vagr...
Lucas Arruda
 
PHP Conference Brasil 2013 - Virtualização e Provisionamento de Ambientes c...
Lucas Arruda
 
TDC2013 - PHP - Virtualização e Provisionamento de Ambientes com Vagrant e ...
Lucas Arruda
 

Recently uploaded (20)

PDF
Bitcoin for Millennials podcast with Bram, Power Laws of Bitcoin
Stephen Perrenod
 
PDF
HCIP-Data Center Facility Deployment V2.0 Training Material (Without Remarks ...
mcastillo49
 
PDF
LLMs.txt: Easily Control How AI Crawls Your Site
Keploy
 
PDF
Newgen 2022-Forrester Newgen TEI_13 05 2022-The-Total-Economic-Impact-Newgen-...
darshakparmar
 
PDF
Timothy Rottach - Ramp up on AI Use Cases, from Vector Search to AI Agents wi...
AWS Chicago
 
PDF
Building Real-Time Digital Twins with IBM Maximo & ArcGIS Indoors
Safe Software
 
PDF
CIFDAQ Weekly Market Wrap for 11th July 2025
CIFDAQ
 
PPTX
UiPath Academic Alliance Educator Panels: Session 2 - Business Analyst Content
DianaGray10
 
PDF
Newgen Beyond Frankenstein_Build vs Buy_Digital_version.pdf
darshakparmar
 
PDF
Blockchain Transactions Explained For Everyone
CIFDAQ
 
PPTX
Building Search Using OpenSearch: Limitations and Workarounds
Sease
 
PDF
HubSpot Main Hub: A Unified Growth Platform
Jaswinder Singh
 
PPTX
OpenID AuthZEN - Analyst Briefing July 2025
David Brossard
 
PDF
CIFDAQ Token Spotlight for 9th July 2025
CIFDAQ
 
PDF
Exolore The Essential AI Tools in 2025.pdf
Srinivasan M
 
PDF
July Patch Tuesday
Ivanti
 
PDF
New from BookNet Canada for 2025: BNC BiblioShare - Tech Forum 2025
BookNet Canada
 
PDF
Reverse Engineering of Security Products: Developing an Advanced Microsoft De...
nwbxhhcyjv
 
PDF
Presentation - Vibe Coding The Future of Tech
yanuarsinggih1
 
PDF
Agentic AI lifecycle for Enterprise Hyper-Automation
Debmalya Biswas
 
Bitcoin for Millennials podcast with Bram, Power Laws of Bitcoin
Stephen Perrenod
 
HCIP-Data Center Facility Deployment V2.0 Training Material (Without Remarks ...
mcastillo49
 
LLMs.txt: Easily Control How AI Crawls Your Site
Keploy
 
Newgen 2022-Forrester Newgen TEI_13 05 2022-The-Total-Economic-Impact-Newgen-...
darshakparmar
 
Timothy Rottach - Ramp up on AI Use Cases, from Vector Search to AI Agents wi...
AWS Chicago
 
Building Real-Time Digital Twins with IBM Maximo & ArcGIS Indoors
Safe Software
 
CIFDAQ Weekly Market Wrap for 11th July 2025
CIFDAQ
 
UiPath Academic Alliance Educator Panels: Session 2 - Business Analyst Content
DianaGray10
 
Newgen Beyond Frankenstein_Build vs Buy_Digital_version.pdf
darshakparmar
 
Blockchain Transactions Explained For Everyone
CIFDAQ
 
Building Search Using OpenSearch: Limitations and Workarounds
Sease
 
HubSpot Main Hub: A Unified Growth Platform
Jaswinder Singh
 
OpenID AuthZEN - Analyst Briefing July 2025
David Brossard
 
CIFDAQ Token Spotlight for 9th July 2025
CIFDAQ
 
Exolore The Essential AI Tools in 2025.pdf
Srinivasan M
 
July Patch Tuesday
Ivanti
 
New from BookNet Canada for 2025: BNC BiblioShare - Tech Forum 2025
BookNet Canada
 
Reverse Engineering of Security Products: Developing an Advanced Microsoft De...
nwbxhhcyjv
 
Presentation - Vibe Coding The Future of Tech
yanuarsinggih1
 
Agentic AI lifecycle for Enterprise Hyper-Automation
Debmalya Biswas
 

1st CI&T Lightning Talks: Writing better code with Object Calisthenics

  • 1. Writing better code with Object Calisthenics Lucas Arruda [email protected] github.com/larruda Adapted from Jeff Bay’s paper from “The ThoughtWorks Anthology” and Guilherme Blanco’s presentation.
  • 4. 7 code qualities cohesion loose coupling no redundancy encapsulation testability readability focus
  • 6. 1. One level of indentation per method class Board { ... String board() { StringBuffer buf = new StringBuffer(); for (int i = 0; i < 10; i++) { for (int j = 0; j < 10; j++) buf.append(data[i][j]); buf.append(“n”); } return buf.toString(); } }
  • 7. 1. One level of indentation per method class Board { ... String Board() { StringBuffer buf = new StringBuffer(); collectRows(buf); return buf.toString(); } void collectRows(StringBuffer buf) { for (int i = 0; i < 10; i++) collectRow(buf, i); } void collectRow(StringBuffer buf, int row) { for (int i = 0; i < 10; i++) Buf.append(data[row][i]); buf.append(“n”); } }
  • 8. 1. One level of indentation per method public function validateForm($filters='', $validators='', $options='') { $data = $_POST; $input = new Zend_Filter_Input($filters, $validators, $data); $input->setDefaultEscapeFilter(new Zend_Filter_StringTrim()); if ($input->hasInvalid() || $input->hasMissing()) { foreach ($input->getMessages() as $field => $messageList) { foreach ($messageList as $message) { if (strpos($message, "empty")) { throw new Tss_FormException( "The field {$field} cannot be empty!", 3, 'javascript:history.back();' ); } else { throw new Tss_FormException( "{$message}", 3, 'javascript:history.back();' ); } } } } return $input; }
  • 9. 1. One level of indentation per method public function validateForm($filters='', $validators='', $options='') { $data = $_POST; $input = new Zend_Filter_Input($filters, $validators, $data); $input->setDefaultEscapeFilter(new Zend_Filter_StringTrim()); if ( ! ($input->hasInvalid() || $input->hasMissing())) { return $input; } foreach ($input->getMessages() as $field => $messageList) { foreach ($messageList as $message) { if (strpos($message, "empty")) { throw new Tss_FormException( "The field {$field} cannot be empty!", 3, 'javascript:history.back();' ); } else { throw new Tss_FormException( "{$message}", 3, 'javascript:history.back();' ); } } } }
  • 10. 1. One level of indentation per method public function validateForm($filters='', $validators='', ... { $data = $_POST; $input = new Zend_Filter_Input ($filters, $validators, $data); $input->setDefaultEscapeFilter( new Zend_Filter_StringTrim ()); if ( ! ($input->hasInvalid() || $input->hasMissing())) { return $input; } foreach ($input->getMessages() as $field => $messageList) { foreach ($messageList as $message) { $errorMessage = (strpos($message, "empty") === false) ? "The field {$field} cannot be empty!" : "{$message}"; throw new Tss_FormException ( $errorMessage, 3, 'javascript:history.back();' ); } } }
  • 11. 1. One level of indentation per method public function validateForm($filters='', $validators='', ... { $data = $_POST; $input = new Zend_Filter_Input ($filters, $validators, $data); $input->setDefaultEscapeFilter( new Zend_Filter_StringTrim ()); if ( ! ($input->hasInvalid() || $input->hasMissing())) { return $input; } foreach ($input->getMessages() as $field => $messageList) { $messageKey = key($message); $message = $message[$messageKey]; $errorMessage = (strpos($message, "empty") === false) ? "The field {$field} cannot be empty!" : "{$message}"; throw new Tss_FormException ( $errorMessage, 3, 'javascript:history.back();' ); } }
  • 12. 2. Don’t use the ELSE keyword if (status == DONE) { doSomething(); } else { … }
  • 14. 2. Don’t use the ELSE keyword class Board { ... String board(StringBuffer buf) { if (buf.length()) { return buf.toString(); } else { collectRows(buf); return buf.toString(); } } ... }
  • 15. 2. Don’t use the ELSE keyword class Board { ... String board(StringBuffer buf) { if (!buf.length()) { collectRows(buf); } return buf.toString(); } ... }
  • 16. 2. Don’t use the ELSE keyword function login() { $login = $this->input->post('email', true); $password = $this->input->post('password', true); $reference = $this->input->post('reference', true); if ($this->clients_model->login($login, $password)) { redirect( $reference); } else { $this->session->set_flashdata( 'error' , 'User or password invalid.' ); $this->session->set_flashdata( 'reference', $reference); redirect( 'clients'); } }
  • 17. 2. Don’t use the ELSE keyword function login() { $login = $this->input->post('email', true); $password = $this->input->post('password', true); $reference = $this->input->post('reference', true); if (!$this->clients_model->login($login, $password)) { $this->session->set_flashdata( 'error' , 'User or password invalid.' ); $this->session->set_flashdata( 'reference', $reference); $reference = 'clients'; } redirect($reference); }
  • 18. 3. Wrap all primitives and Strings
  • 19. If the primitive type has a behavior it should be encapsulated
  • 20. 3. Wrap all primitives and Strings class UIComponent { // ... public function repaint($animate = true) { // … } // ... $component->repaint(false); }
  • 21. 3. Wrap all primitives and Strings class UIComponent { // ... public function repaint(Animate $animate) { // ... } } class Animate { public $animate; public function __construct($animate = true) { $this->animate = $animate; } } // ... $component->repaint(new Animate(false));
  • 22. 4. First class collections Any class that contains a collection/array should not contain any other member variables Java Collections follow this rule
  • 23. 4. First class collections Transversable Countable Iterator Filtering Mapping Combining
  • 24. 5. One dot/arrow per line Sign of misplaced responsibilities The Law of Demeter “Only talk to your friends”
  • 25. 5. One dot/arrow per line class Board { ... class Piece { ... String representation; } class Location { ... Piece current; } String boardRepresentation () { StringBuffer buf = new StringBuffer(); for (Location l: squares()) buf .append(l.current.representation .substring(0, 1)); return buf.toString(); } }
  • 26. 5. One dot/arrow per line class Board { ... class Piece { ... private String representation; String character() { return representation.substring(0, 1); } void addTo(StringBuffer buf) { buf.append(character()); } } class Location { ... private Piece current; void addTo(StringBuffer buf) { current.addTo(buf); } } String boardRepresentation() { StringBuffer buf = new StringBuffer(); for (Location l: squares()) l.addTo(buf); return buf.toString(); } }
  • 27. 6. Don’t abbreviate Are you writing the same name repeatedly? method being used multiple times sign of code duplication Is the method name too long? class with multiple responsibilities missing additional class redundancy
  • 28. 7. Keep all entities small Java No class over 50 lines No packages over 10 files PHP No class over 100 lines No packages over 15 files Packages, like classes, should be cohesive and have a purpose
  • 29. 8. No classes with more than two/five instance variables Improve cohesion Split on more entities
  • 30. 9. No getters/setters/properties Improve encapsulation “Tell, don’t ask”