object calisthenics
TRANSCRIPT
![Page 1: Object Calisthenics](https://reader037.vdocuments.net/reader037/viewer/2022100215/554f3d2bb4c90572088b5091/html5/thumbnails/1.jpg)
Object Calisthenics9 steps to better software design today, by Jeff Bay
By: DarwinApril 30, 2014
![Page 2: Object Calisthenics](https://reader037.vdocuments.net/reader037/viewer/2022100215/554f3d2bb4c90572088b5091/html5/thumbnails/2.jpg)
Before we start...
As developers we all are aware of the core concepts that make up good OO code…
cohesion, loose coupling, no redundancy, encapsulation, testability, readability, maintainability, etc.
But the question is, are we really implementing these concepts properly in code?
![Page 3: Object Calisthenics](https://reader037.vdocuments.net/reader037/viewer/2022100215/554f3d2bb4c90572088b5091/html5/thumbnails/3.jpg)
Why does myCODE suck?
Is it MAINTAINABLE? Is it READABLE?
Is it TESTABLE?Is it REUSABLE?
Let’s ask ourselves of the following...
![Page 4: Object Calisthenics](https://reader037.vdocuments.net/reader037/viewer/2022100215/554f3d2bb4c90572088b5091/html5/thumbnails/4.jpg)
And what does it have to do with good OO coding?
What is Object Calisthenics?
Object Calisthenics: 9 steps to better software design today, by Jeff Bay
![Page 5: Object Calisthenics](https://reader037.vdocuments.net/reader037/viewer/2022100215/554f3d2bb4c90572088b5091/html5/thumbnails/5.jpg)
Calisthenics ( cal·is·then·ics )Definition :
Calisthenics are a form of dynamic exercise consisting of a variety of simple, often rhythmical, movements, generally using minimal equipment or apparatus.
Object Calisthenics Definition :
A variety of simple, often rhythmical, exercises to achieve better OO (Object Oriented) design and code quality.
Object Calisthenics: 9 steps to better software design today, by Jeff Bay
![Page 6: Object Calisthenics](https://reader037.vdocuments.net/reader037/viewer/2022100215/554f3d2bb4c90572088b5091/html5/thumbnails/6.jpg)
1. One level of indentation per method2. Don’t use the ELSE keyword3. Wrap all primitives and Strings4. First class collections5. One -> per line6. Don’t abbreviate7. Keep all entities small8. Limit the number of instance variables
in a class (max: 2~5)9. Do use accessors (getters/setters)
Object Calisthenics: 9 steps to better software design today, by Jeff Bay
![Page 7: Object Calisthenics](https://reader037.vdocuments.net/reader037/viewer/2022100215/554f3d2bb4c90572088b5091/html5/thumbnails/7.jpg)
OC #1
“Only one level of indentation per
method”
Object Calisthenics: 9 steps to better software design today, by Jeff Bay
![Page 8: Object Calisthenics](https://reader037.vdocuments.net/reader037/viewer/2022100215/554f3d2bb4c90572088b5091/html5/thumbnails/8.jpg)
function validateProducts ($products) {
foreach ($products as $rawProduct) {
$fields = array_keys($rawProduct);
foreach ($requiredFields as $requiredField) {
if (!in_array($requiredField, $fields)) {
$valid = false;
}
}
}
}
Object Calisthenics: 9 steps to better software design today, by Jeff Bay
![Page 9: Object Calisthenics](https://reader037.vdocuments.net/reader037/viewer/2022100215/554f3d2bb4c90572088b5091/html5/thumbnails/9.jpg)
OC #1: Only one level of indentation per method
• A giant method lacks cohesiveness.• Try to ensure that each method does exactly one thing – one
control structure, or one block of statements, per method.
• Nested control structures in a method, works at multiple levels of abstraction which means it does more than one thing.
Object Calisthenics: 9 steps to better software design today, by Jeff Bay
![Page 10: Object Calisthenics](https://reader037.vdocuments.net/reader037/viewer/2022100215/554f3d2bb4c90572088b5091/html5/thumbnails/10.jpg)
Basically…
• Do one thing per method• one control structure• one block of statements
• Avoid nested control structures• it means you are doing more than one thing
Object Calisthenics: 9 steps to better software design today, by Jeff Bay
![Page 11: Object Calisthenics](https://reader037.vdocuments.net/reader037/viewer/2022100215/554f3d2bb4c90572088b5091/html5/thumbnails/11.jpg)
Object Calisthenics: 9 steps to better software design today, by Jeff Bay
function validateProductList ( $products) {
$invalidProducts = array_filter($products, ‘isInvalidProduct’ );
return (count($invalidProducts) === 0);
}
function isInvalidProduct ( $rawProduct) {
$requiredFields = array(‘price’, ‘name’, ‘description’, ‘type’);
$fields = array_keys($rawProduct);
$missingFields = array_diff($requiredFields, $fields);
return (count($missingFields) > 0);
}
reusable method
![Page 12: Object Calisthenics](https://reader037.vdocuments.net/reader037/viewer/2022100215/554f3d2bb4c90572088b5091/html5/thumbnails/12.jpg)
Benefits…
• Cohesiveness• Methods do only one thing• Increases re-use
Object Calisthenics: 9 steps to better software design today, by Jeff Bay
![Page 13: Object Calisthenics](https://reader037.vdocuments.net/reader037/viewer/2022100215/554f3d2bb4c90572088b5091/html5/thumbnails/13.jpg)
OC #2
“Do not use the ‘else‘ keyword”
Object Calisthenics: 9 steps to better software design today, by Jeff Bay
![Page 14: Object Calisthenics](https://reader037.vdocuments.net/reader037/viewer/2022100215/554f3d2bb4c90572088b5091/html5/thumbnails/14.jpg)
if ($form->isValid) {
$repository = $this->getRepository(‘MyBundle:Post’);
if (!$repository->exists($entity)) {
$repository->save($entity);
return $this->redirect(‘create_ok’);
} else {
$error = “Post Title already exists” ;
return array(‘form’ => $form, ‘error’ => $error);
}
} else {
$error = “Invalid fields”;
return array(‘form’ => $form, ‘error’ => $error);
}
ELSE
Object Calisthenics: 9 steps to better software design today, by Jeff Bay
![Page 15: Object Calisthenics](https://reader037.vdocuments.net/reader037/viewer/2022100215/554f3d2bb4c90572088b5091/html5/thumbnails/15.jpg)
OC #2: Do not use the ‘else’ keyword
• Conditionals are also a frequent source of duplication.
if (status == ‘DONE’) {doSomething();
} else {…
}
Object Calisthenics: 9 steps to better software design today, by Jeff Bay
![Page 16: Object Calisthenics](https://reader037.vdocuments.net/reader037/viewer/2022100215/554f3d2bb4c90572088b5091/html5/thumbnails/16.jpg)
Basically…
• Nested conditionals & long case statements• hard to follow
• Frequent source of code duplication
Object Calisthenics: 9 steps to better software design today, by Jeff Bay
![Page 17: Object Calisthenics](https://reader037.vdocuments.net/reader037/viewer/2022100215/554f3d2bb4c90572088b5091/html5/thumbnails/17.jpg)
$repository = $this->getRepository(‘MyBundle:Post’);
if (!$form->isValid) {
return array(‘form’ => $form, ‘error’ => ‘Invalid fields’);
}
if ($repository->exists($entity)) {
return array(‘form’ => $form, ‘error’ => ‘Post Title already exists’ );
}
$repository->save($entity);
return $this->redirect(‘create_ok’);
early return
Object Calisthenics: 9 steps to better software design today, by Jeff Bay
![Page 18: Object Calisthenics](https://reader037.vdocuments.net/reader037/viewer/2022100215/554f3d2bb4c90572088b5091/html5/thumbnails/18.jpg)
Benefits…
• Helps avoid code duplication• Makes code clearer, easier to read
Object Calisthenics: 9 steps to better software design today, by Jeff Bay
![Page 19: Object Calisthenics](https://reader037.vdocuments.net/reader037/viewer/2022100215/554f3d2bb4c90572088b5091/html5/thumbnails/19.jpg)
OC #3
“Wrap all primitive types and strings, if
it has behavior”
Object Calisthenics: 9 steps to better software design today, by Jeff Bay
![Page 20: Object Calisthenics](https://reader037.vdocuments.net/reader037/viewer/2022100215/554f3d2bb4c90572088b5091/html5/thumbnails/20.jpg)
class UIComponent
{
//...
public function repaint($animate = true) {
//...
}
}
//...
$component->repaint(false);
unclear operation
Object Calisthenics: 9 steps to better software design today, by Jeff Bay
![Page 21: Object Calisthenics](https://reader037.vdocuments.net/reader037/viewer/2022100215/554f3d2bb4c90572088b5091/html5/thumbnails/21.jpg)
OC #3: Wrap all primitive types and strings, if it has behavior
• To give the programmer additional information about what the value is and why it is being used
• This rule tries to encapsulate all the primitives within objects for these to work in all our code in an OO-way.
Object Calisthenics: 9 steps to better software design today, by Jeff Bay
![Page 22: Object Calisthenics](https://reader037.vdocuments.net/reader037/viewer/2022100215/554f3d2bb4c90572088b5091/html5/thumbnails/22.jpg)
class UIComponent
{
//...
public function repaint(Animate $animate) {
//...
}
}
class Animate
{
public $animate
public function __construct($animate = true) {
$this->animate = $animate;
}
}
//...
$component->repaint(new Animate(false));
This can now encapsulate all
animation related operations
Object Calisthenics: 9 steps to better software design today, by Jeff Bay
![Page 23: Object Calisthenics](https://reader037.vdocuments.net/reader037/viewer/2022100215/554f3d2bb4c90572088b5091/html5/thumbnails/23.jpg)
<?php
class IntegerNumber
{
private $number;
public function __construct($number)
{
$this->number = $number;
}
//...
}
An example of how we can wrap the int
primitive.
Object Calisthenics: 9 steps to better software design today, by Jeff Bay
![Page 24: Object Calisthenics](https://reader037.vdocuments.net/reader037/viewer/2022100215/554f3d2bb4c90572088b5091/html5/thumbnails/24.jpg)
<?php
class Item
{
final public static function find(Id $id)
{
// do find...
}
final public static function create(Id $id, array $data)
{
// do create...
}
}
$id is now guaranteed to be valid.
$id is now guaranteed to be valid.
Object Calisthenics: 9 steps to better software design today, by Jeff Bay
![Page 25: Object Calisthenics](https://reader037.vdocuments.net/reader037/viewer/2022100215/554f3d2bb4c90572088b5091/html5/thumbnails/25.jpg)
Benefits…
• More maintainable code• Helps identify what should be an Object• Type hinting• Encapsulation of operations• Context of value is more obvious
Object Calisthenics: 9 steps to better software design today, by Jeff Bay
![Page 26: Object Calisthenics](https://reader037.vdocuments.net/reader037/viewer/2022100215/554f3d2bb4c90572088b5091/html5/thumbnails/26.jpg)
OC #4
“Use first class collections”
Object Calisthenics: 9 steps to better software design today, by Jeff Bay
![Page 27: Object Calisthenics](https://reader037.vdocuments.net/reader037/viewer/2022100215/554f3d2bb4c90572088b5091/html5/thumbnails/27.jpg)
$collection->getIterator();
$collection->filter(...);
$collection->append(...);
$collection->map(...);
Object Calisthenics: 9 steps to better software design today, by Jeff Bay
![Page 28: Object Calisthenics](https://reader037.vdocuments.net/reader037/viewer/2022100215/554f3d2bb4c90572088b5091/html5/thumbnails/28.jpg)
OC #4: Use first class collections
• Any class that contains a collection should contain no other member variables.
• Each collection gets wrapped in its own class. So now, behaviors related to the collection have a home.
• Class will contain related behaviors.
Object Calisthenics: 9 steps to better software design today, by Jeff Bay
![Page 29: Object Calisthenics](https://reader037.vdocuments.net/reader037/viewer/2022100215/554f3d2bb4c90572088b5091/html5/thumbnails/29.jpg)
class Items
{
private $item = [];
public function add(Item $item, array $data)
{
// do add...
}
public function filter(array $filters)
{
// do filter...
}
}
Object Calisthenics: 9 steps to better software design today, by Jeff Bay
![Page 30: Object Calisthenics](https://reader037.vdocuments.net/reader037/viewer/2022100215/554f3d2bb4c90572088b5091/html5/thumbnails/30.jpg)
Benefits…
• Implements collection operations• Uses SPL interfaces
Object Calisthenics: 9 steps to better software design today, by Jeff Bay
![Page 31: Object Calisthenics](https://reader037.vdocuments.net/reader037/viewer/2022100215/554f3d2bb4c90572088b5091/html5/thumbnails/31.jpg)
OC #5
“Only one -> per line”
Object Calisthenics: 9 steps to better software design today, by Jeff Bay
![Page 32: Object Calisthenics](https://reader037.vdocuments.net/reader037/viewer/2022100215/554f3d2bb4c90572088b5091/html5/thumbnails/32.jpg)
$this->base_url = $this->CI->config->site_url().’/’.$this->CI->uri->segment(1).$this->CI->uri->slash_segment(2, ‘both’);
$this->base_uri = $this->CI->uri->segment(1).$this->CI->uri->slash_segment(2, ‘leading’);
$this->base_uri = $this->getCI()->getUriBuilder()->getBaseUri(‘leading’);
Move everything to uri object
no whitespace
properties are harder to mock
Object Calisthenics: 9 steps to better software design today, by Jeff Bay
![Page 33: Object Calisthenics](https://reader037.vdocuments.net/reader037/viewer/2022100215/554f3d2bb4c90572088b5091/html5/thumbnails/33.jpg)
$this->manager->getConfig()->getSegment()->setName(‘foo’);
properties are harder to mock
previous call could return NULL
Object Calisthenics: 9 steps to better software design today, by Jeff Bay
![Page 34: Object Calisthenics](https://reader037.vdocuments.net/reader037/viewer/2022100215/554f3d2bb4c90572088b5091/html5/thumbnails/34.jpg)
OC #5: Only one -> per line
• An object should not deal with two other objects at once
Object Calisthenics: 9 steps to better software design today, by Jeff Bay
![Page 35: Object Calisthenics](https://reader037.vdocuments.net/reader037/viewer/2022100215/554f3d2bb4c90572088b5091/html5/thumbnails/35.jpg)
Basically…
• Multiple ->• indicate misplaced responsibilities• violate encapsulation
• Law of Demeter• “Talk only to your friends”
Object Calisthenics: 9 steps to better software design today, by Jeff Bay
![Page 36: Object Calisthenics](https://reader037.vdocuments.net/reader037/viewer/2022100215/554f3d2bb4c90572088b5091/html5/thumbnails/36.jpg)
Benefits…
• Readability• Easier Mocking• Easier to Debug
Object Calisthenics: 9 steps to better software design today, by Jeff Bay
![Page 37: Object Calisthenics](https://reader037.vdocuments.net/reader037/viewer/2022100215/554f3d2bb4c90572088b5091/html5/thumbnails/37.jpg)
OC #6
“Do NOT abbreviate”
Object Calisthenics: 9 steps to better software design today, by Jeff Bay
![Page 38: Object Calisthenics](https://reader037.vdocuments.net/reader037/viewer/2022100215/554f3d2bb4c90572088b5091/html5/thumbnails/38.jpg)
if ($sx >= $sy) {
if ($sx > $strSysMatImgW) {
//…
}
if ($ny > $strSysMatImgH) {
//…
}
} else {
if ($sy > $strSysMatImgH) {
//…
}
if ($nx > $strSysMatImgW) {
//…
}
}
?
?
?
?
Object Calisthenics: 9 steps to better software design today, by Jeff Bay
![Page 39: Object Calisthenics](https://reader037.vdocuments.net/reader037/viewer/2022100215/554f3d2bb4c90572088b5091/html5/thumbnails/39.jpg)
OC #6: Do NOT abbreviate
• Abbreviations can be confusing, and they tend to hide larger problems.
• Keep class and method names to 1-2 words, and avoid names that duplicate the context.
Object Calisthenics: 9 steps to better software design today, by Jeff Bay
![Page 40: Object Calisthenics](https://reader037.vdocuments.net/reader037/viewer/2022100215/554f3d2bb4c90572088b5091/html5/thumbnails/40.jpg)
Basically…
• Keep names to one-two words• class names• method names• entities
Object Calisthenics: 9 steps to better software design today, by Jeff Bay
![Page 41: Object Calisthenics](https://reader037.vdocuments.net/reader037/viewer/2022100215/554f3d2bb4c90572088b5091/html5/thumbnails/41.jpg)
function getPage($data) { ... }
function startProcess() { ... }
$tr->process(“site.login”);
Use a thesaurus: fork, create, begin, open
Easy understanding, complete scope:
$translatorService
Use clearer names:fetchPage()
downloadPage()
get from where?
table row?
Object Calisthenics: 9 steps to better software design today, by Jeff Bay
![Page 42: Object Calisthenics](https://reader037.vdocuments.net/reader037/viewer/2022100215/554f3d2bb4c90572088b5091/html5/thumbnails/42.jpg)
Benefits…
• Clearer communication• Indicates underlying problems
Object Calisthenics: 9 steps to better software design today, by Jeff Bay
![Page 43: Object Calisthenics](https://reader037.vdocuments.net/reader037/viewer/2022100215/554f3d2bb4c90572088b5091/html5/thumbnails/43.jpg)
OC #7
“Keep all entities small”
Object Calisthenics: 9 steps to better software design today, by Jeff Bay
![Page 44: Object Calisthenics](https://reader037.vdocuments.net/reader037/viewer/2022100215/554f3d2bb4c90572088b5091/html5/thumbnails/44.jpg)
OC #7: Keep classes small
• 200 lines per class (including docblocks)
• 15 - 20 lines per method
• 10 methods per class
• 15 classes per namespace (package or folder)
Object Calisthenics: 9 steps to better software design today, by Jeff Bay
![Page 45: Object Calisthenics](https://reader037.vdocuments.net/reader037/viewer/2022100215/554f3d2bb4c90572088b5091/html5/thumbnails/45.jpg)
Benefits…
• Easier to grasp quickly• Single responsibility• Objective method• Slimmer namespaces• Less clunky folders
Object Calisthenics: 9 steps to better software design today, by Jeff Bay
![Page 46: Object Calisthenics](https://reader037.vdocuments.net/reader037/viewer/2022100215/554f3d2bb4c90572088b5091/html5/thumbnails/46.jpg)
OC #8
“Limit the number of instance variables
in a class (max: 2 5)”
Object Calisthenics: 9 steps to better software design today, by Jeff Bay
![Page 47: Object Calisthenics](https://reader037.vdocuments.net/reader037/viewer/2022100215/554f3d2bb4c90572088b5091/html5/thumbnails/47.jpg)
class Client
{
private $_adapter;
private $_cache;
private $_logger;
//...
}
Limit: 2 - 5
Object Calisthenics: 9 steps to better software design today, by Jeff Bay
![Page 48: Object Calisthenics](https://reader037.vdocuments.net/reader037/viewer/2022100215/554f3d2bb4c90572088b5091/html5/thumbnails/48.jpg)
Benefits…
• Shorter dependency list• Better understanding of commonality
Object Calisthenics: 9 steps to better software design today, by Jeff Bay
![Page 49: Object Calisthenics](https://reader037.vdocuments.net/reader037/viewer/2022100215/554f3d2bb4c90572088b5091/html5/thumbnails/49.jpg)
OC #9
“Do not use accessors (getter/setter)”
Object Calisthenics: 9 steps to better software design today, by Jeff Bay
![Page 50: Object Calisthenics](https://reader037.vdocuments.net/reader037/viewer/2022100215/554f3d2bb4c90572088b5091/html5/thumbnails/50.jpg)
class Tally
{
public $total = 0;
public function add($amount)
{
$this->total += $amount;
}
}
$tally = new Tally();
$tally->add(1);
// some other code...
$tally->total = -1;
// some other code...
$tally->add(1);
echo $tally->total . PHP_EOL
$total can be changed without this instance knowing
causes unexpected results
Object Calisthenics: 9 steps to better software design today, by Jeff Bay
![Page 51: Object Calisthenics](https://reader037.vdocuments.net/reader037/viewer/2022100215/554f3d2bb4c90572088b5091/html5/thumbnails/51.jpg)
class Tally
{
private $total = 0;
public function add($amount)
{
$this->total += $amount;
}
public function getTotal()
{
return $this->total;
}
}
$tally = new Tally();
$tally->add(1);
$tally->add(1);
echo $tally->getTotal() . PHP_EOL
total cannot be “reset”
no unexpected results
Object Calisthenics: 9 steps to better software design today, by Jeff Bay
![Page 52: Object Calisthenics](https://reader037.vdocuments.net/reader037/viewer/2022100215/554f3d2bb4c90572088b5091/html5/thumbnails/52.jpg)
Benefits…
• Injector operations• Encapsulation of transformations
Object Calisthenics: 9 steps to better software design today, by Jeff Bay
![Page 53: Object Calisthenics](https://reader037.vdocuments.net/reader037/viewer/2022100215/554f3d2bb4c90572088b5091/html5/thumbnails/53.jpg)
1. “Only one level of indentation per method”
2. “Do not use the ‘else‘ keyword”
3. “Wrap all primitive types and strings, if it has behavior”
4. “Use first class collections”
5. “Only one -> per line”
6. “Do NOT abbreviate”
7. “Keep all entities small”
8. “Limit the number of instance variables in a class (max: 2 5)”
9. “Do not use accessors (getter/setter)”
The Recap...
![Page 54: Object Calisthenics](https://reader037.vdocuments.net/reader037/viewer/2022100215/554f3d2bb4c90572088b5091/html5/thumbnails/54.jpg)
• To visualize and implement the holy grail of object oriented programming – encapsulation of data
• To use polymorphism appropriately
• To encourage concise and straightforward naming standards
• To craft code that has no duplication in code or idea
The Aim...
![Page 55: Object Calisthenics](https://reader037.vdocuments.net/reader037/viewer/2022100215/554f3d2bb4c90572088b5091/html5/thumbnails/55.jpg)
• http://www.bennadel.com/resources/uploads/2012/ObjectCalisthenics.pdf• http://www.slideshare.net/rdohms/your-code-sucks-lets-fix-it• http://www.slideshare.net/chadwick0678/getting-your-code-into-shape-with-object
References
![Page 56: Object Calisthenics](https://reader037.vdocuments.net/reader037/viewer/2022100215/554f3d2bb4c90572088b5091/html5/thumbnails/56.jpg)