Object calisthenics (PHPConPL 2016)

79
Object Calisthenics 9 steps to better OO code

Transcript of Object calisthenics (PHPConPL 2016)

Page 1: Object calisthenics (PHPConPL 2016)

ObjectCalisthenics9stepstobetterOOcode

Page 2: Object calisthenics (PHPConPL 2016)

Agenda

Learnhowtomakeourcodemore:

readablereusabletestablemaintainable

Page 3: Object calisthenics (PHPConPL 2016)

Calisthenics

Page 4: Object calisthenics (PHPConPL 2016)

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

Page 5: Object calisthenics (PHPConPL 2016)

"Calisthenicsareexercisesconsistingofavarietyofgrossmotormovements;often

rhythmicalandgenerallywithoutequipmentorapparatus."

Wikipedia

Page 7: Object calisthenics (PHPConPL 2016)

WrittenforJava

Page 8: Object calisthenics (PHPConPL 2016)

Whybother?

Page 9: Object calisthenics (PHPConPL 2016)

Codeisreadmorethanit'swritten

Page 10: Object calisthenics (PHPConPL 2016)

Rule#1

Onlyonelevelofindentationpermethod

Page 11: Object calisthenics (PHPConPL 2016)

classBoard{publicfunction__construct(array$data){$buf='';//0for($i=0;$i<10;$i++){//1for($j=0;$j<10;$j++){//2$buf.=$data[$i][$j]}}

return$buf;}}

Page 12: Object calisthenics (PHPConPL 2016)

classBoard{publicfunction__construct(array$data){$buf='';collectRows($buf);

return$buf;}

privatefunctioncollectRows($buf){for($i=0;$i<10;$i++){collectRow($buf,$i);}}

privatefunctioncollectRow($buf,$row){for($i=0;$i<10;$i++){$buf.=$data[$row][$i];}}}

Page 13: Object calisthenics (PHPConPL 2016)

Benefits

SingleresponsibilityBetternamingShortermethodsReusablemethods

Page 14: Object calisthenics (PHPConPL 2016)

Rule#2

Donotuseelsekeyword

Page 15: Object calisthenics (PHPConPL 2016)

if(...){...}elseif(...){...}elseif(...){...}elseif(...){...}elseif(...){...}elseif(...){...}else{...}

Page 16: Object calisthenics (PHPConPL 2016)

publicfunctionlogin($username,$password){if($this->userRepository->isValid($username,$password)){redirect("homepage");}else{addFlash("error","Badcredentials");redirect("login");}}

Page 17: Object calisthenics (PHPConPL 2016)

publicfunctionlogin($username,$password){if($this->userRepository->isValid($username,$password)){returnredirect("homepage");}

addFlash("error","Badcredentials");

returnredirect("login");}

Page 18: Object calisthenics (PHPConPL 2016)
Page 19: Object calisthenics (PHPConPL 2016)

Extractcode

Page 20: Object calisthenics (PHPConPL 2016)

Defaultvalue

Page 21: Object calisthenics (PHPConPL 2016)

Polymorphism

Page 22: Object calisthenics (PHPConPL 2016)

Strategypattern

Page 23: Object calisthenics (PHPConPL 2016)

Statepattern

Page 24: Object calisthenics (PHPConPL 2016)

BenefitsAvoidscodeduplicationLowercomplexityReadability

Page 25: Object calisthenics (PHPConPL 2016)

Rule#3

Wrapprimitivetypesifithasbehaviour

Page 26: Object calisthenics (PHPConPL 2016)

ValueObjectinDDD

Page 27: Object calisthenics (PHPConPL 2016)

publicfunctioncheckDate(int$year,int$month,int$day){...}

//10thofDecemberor12thofOctober?$validator->checkDate(2016,10,12);

Page 28: Object calisthenics (PHPConPL 2016)

publicfunctioncheckDate(Year$year,Month$month,Day$day){...}

$validator->checkDate(newYear(2016),newMonth(10),newDay(12));

Page 29: Object calisthenics (PHPConPL 2016)

BenefitsEncapsulationTypehintingAttractssimilarbehaviour

Page 30: Object calisthenics (PHPConPL 2016)

Rule#4

Onlyone->perline

Page 31: Object calisthenics (PHPConPL 2016)

OK:Fluentinterface

Page 32: Object calisthenics (PHPConPL 2016)

$validator->addFilter(newEmailFilter())->addFilter(newNotEmptyFilter());

Page 33: Object calisthenics (PHPConPL 2016)

NotOK:getterchain

Page 34: Object calisthenics (PHPConPL 2016)

$token=$this->getService(Service::AUTH)->authUser($user,$password)->getResult()->getToken();

//1.Whatifnonobjectisreturned?//2.Howaboutexceptionshandling?

Page 35: Object calisthenics (PHPConPL 2016)

classLocation{/**@varPiece*/publiccurrent;}

classPiece{/**@varstring*/publicrepresentation;}

classBoard{publicfunctionboardRepresentation(array$board){$buf='';

foreach($boardas$field){$buf.=substring($field->current->representation,0,1);}

return$buf;}}

Page 36: Object calisthenics (PHPConPL 2016)

classLocation{/**@varPiece*/private$current;

publicfunctionaddTo($buf){return$this->current->addTo($buf);}}classPiece{/**@varstring*/private$representation;

publicfunctioncharacter(){returnsubstring(representation,0,1);}

publicfunctionaddTo($buf){return$buf.$this->character();}}classBoard{publicfunctionboardRepresentation(array$board){$buf='';/**@varLocation$field*/foreach($boardas$field){$field->addTo($buf);}

return$buf;}

Page 37: Object calisthenics (PHPConPL 2016)

BenefitsEncapsulationDemeter'slawOpen/ClosedPrinciple

Page 38: Object calisthenics (PHPConPL 2016)

Rule#5

Donotabbreviate

Page 39: Object calisthenics (PHPConPL 2016)

Whyabbreviate?

Page 40: Object calisthenics (PHPConPL 2016)

Nametoolong?

Page 41: Object calisthenics (PHPConPL 2016)

Toomanyresponsibilities

Page 42: Object calisthenics (PHPConPL 2016)

Split&extract

Page 43: Object calisthenics (PHPConPL 2016)

Duplicatedcode?

Page 44: Object calisthenics (PHPConPL 2016)

Refactor!

Page 45: Object calisthenics (PHPConPL 2016)

BenefitsClearintentionsIndicateunderlyingproblems

Page 46: Object calisthenics (PHPConPL 2016)

Rule#6

Keepyourclassessmall

Page 47: Object calisthenics (PHPConPL 2016)

Whatissmallclass?15-20linespermethod50linesperclass10classespermodule

Page 48: Object calisthenics (PHPConPL 2016)

200linesperclass

Page 49: Object calisthenics (PHPConPL 2016)

10methodsperclass

Page 50: Object calisthenics (PHPConPL 2016)

15classespernamespace

Page 51: Object calisthenics (PHPConPL 2016)

BenefitsSingleResponsibilitySmallernamespaces

Page 52: Object calisthenics (PHPConPL 2016)

Rule#7

Nomorethan25instancevariableperclass

Page 53: Object calisthenics (PHPConPL 2016)

Classshouldhandlesinglevariablestate

Page 54: Object calisthenics (PHPConPL 2016)

Insomecasesitmightbetwovariables

Page 55: Object calisthenics (PHPConPL 2016)
Page 56: Object calisthenics (PHPConPL 2016)

classCartService{private$userService;private$logger;private$cart;private$translationService;private$entityManager;private$authService;

//...}

Page 57: Object calisthenics (PHPConPL 2016)

BenefitsHighcohesionEncapsulationFewerdependencies

Page 58: Object calisthenics (PHPConPL 2016)

Rule#8

Firstclasscollections

Page 59: Object calisthenics (PHPConPL 2016)

Doctrine'sArrayCollection

Page 60: Object calisthenics (PHPConPL 2016)

BenefitsSingleResponsibility

Page 61: Object calisthenics (PHPConPL 2016)

Rule#9

Donotusesetters/getters

Page 62: Object calisthenics (PHPConPL 2016)

Accessorsarefine

Page 63: Object calisthenics (PHPConPL 2016)

Don'tmakedecisionsoutsideofclass

Page 64: Object calisthenics (PHPConPL 2016)

Letclassdoit'sjob

Page 65: Object calisthenics (PHPConPL 2016)

Tell,don'task

Page 66: Object calisthenics (PHPConPL 2016)

classGame{/**@varint*/privatescore;

publicfunctionsetScore(score){$this->score=score;}publicfunctiongetScore(){return$this->score;}}

//Usage$game->setScore($game->getScore()+ENEMY_DESTROYED_SCORE);

Page 67: Object calisthenics (PHPConPL 2016)

classGame{/**@varint*/privatescore;

publicfunctionaddScore($delta){$this->score+=$delta;}}

//Usage$game->addScore(ENEMY_DESTROYED_SCORE);

Page 68: Object calisthenics (PHPConPL 2016)

BenefitsOpen/ClosedPrinciple

Page 69: Object calisthenics (PHPConPL 2016)

Catch'emall!1. Onlyonelevelofindentationpermethod,2. Donotuseelsekeyword,3. Wrapprimitivetypesifithasbehavior,4. Onlyonedotperline,5. Don’tabbreviate,6. Keepyourentitiessmall,7. Nomorethantwoinstancevariableperclass,8. FirstClassCollections,9. Donotuseaccessors10. ???11. PROFIT!

Page 70: Object calisthenics (PHPConPL 2016)

Homework

Page 71: Object calisthenics (PHPConPL 2016)

Createnewprojectupto1000lineslong

Page 72: Object calisthenics (PHPConPL 2016)

Applypresentedrulesasstrictlyaspossible

Page 73: Object calisthenics (PHPConPL 2016)

Drawconculsions

Page 74: Object calisthenics (PHPConPL 2016)

Customizetheserules

Page 75: Object calisthenics (PHPConPL 2016)

Finalthoughts

Page 76: Object calisthenics (PHPConPL 2016)

Thesearenotbestpractices

Page 77: Object calisthenics (PHPConPL 2016)

Thesearejustguidelines

Page 78: Object calisthenics (PHPConPL 2016)

Usewithcaution!

Page 79: Object calisthenics (PHPConPL 2016)

Thankyou!