Caturday will not be stopped!
Presentation by @JeroenDeDauw
bit.ly/clean-functions
A function should do one thing.
It should do it well, and it should do it only.
4 - 5 lines
One level of abstraction
function onFirstPost() {
$messageText = $this->getWelcomeMessageBody();
if ($this->addFooter()) $messageText.=$this->getWelcomeMessageFooter();
$this->emailer->send( $messageText );
foreach ( $this->getReviewers() as $reviewer ) {
$this->reviewerNotifier->notify( $reviewer );
}
}
function onFirstPost() {
$this->sendWelcomeMessage();
$this->notifyReviewers();
}
Predicates of if and while statements
if ( $foo === 'bar' && ( $user->isAllowed( '' ) || $baz )
&& $this->bah() ) {
$this->sendWelcomeMessage();
}
if ( $this->isFirstPost() ) {
$this->sendWelcomeMessage();
}
Bodies of control structures
if ( $this->isFirstPost() ) {
$this->sendWelcomeMessage();
}
foreach ( $this->getReviewers() as $reviewer ) {
$this->notifyReviewer( $reviewer );
}
How much indenting / nesting?
Name length rule
$user->remove();
function remove() {
// ...
$this->removePostsFromDatabase();
// ...
}
Well written prose
if ( $this->isFirstPost() ) {
$this->sendWelcomeMessage();
$this->notifyReviewers();
}
function notifyReviewers() {
foreach ( $this->reviewers as $reviewer ) {
$reviewer->notify( $this->post );
}
}
Well named methods, classes and namespaces act like signposts
So what makes small functions unsettling?
The landscape metaphor
Long functions are familiar.
Like landscapes, we recognize the landmarks
I'm sorry I had to write you such a long letter,
but I did not have time to write you a short one
-- Blaise Pascal
Make functions do multiple things!
renderHtml( true );
function renderHtml( $userIsLoggedIn ) {
// ...
if ( $userIsLoggedIn ) {
// ...
}
// ...
}
function renderHtmlForLoggedInUser() {
}
function renderHtmlForAnonUser() {
}
renderHtmlForLoggedInUser();
function drawCircle( $x, $y, $radius ) {}
function drawCircle( Point $center, $radius ) {}
appendFooter( $report );
$report->appendFooter();
Either do something OR answer something, not both!
public boolean set( String attributeName, String value );
if ( set( "username", "NyanCat" ) )
Same for returning error codes. Error handling is one thing.
CC BY-SA 3.0, Jeroen De Dauw
Clone from GitHub or view at bit.ly/clean-functions
Slide engine: reveal.js, Copyright (C) 2014 Hakim El Hattab