

% add the PATH to retrieve cls and sty beamer styles files
\makeatletter
\providecommand*{\input@path}{}
\edef\input@path{{../../support/beamer/}\input@path}% prepend
\makeatother

% \documentclass{pharoslides}
% \documentclass[aspectratio=169]{pharoslides} % format 16/9
\documentclass[withvideo]{pharoslides} % format 16/9 + incrustation video

\graphicspath{{./figures/}{../}{../../support/beamer/imgs/}}

%Information to be included in the title page:
\title{Avoid Null Checks}
\subtitle{}
\author{Damien Cassou, Stéphane Ducasse and Luc Fabresse}
\institute{http://stephane.ducasse.free.fr}
\date{}
\slidesid{W7S07}

\begin{document}

\frame[plain]{\titlepage}



\begin{frame}[fragile]

\frametitle{Anti If Campaign}

\begin{listing}{}
Main >> showHappiness: animal
   animal isDog
      ifTrue: [ animal shakeTail ].
   animal isDuck
      ifTrue: [ animal quack ].
   animal isCat: [ ... ].
\end{listing}

Branching (with \code{if}) based on the type of an object is bad:

\begin{itemize}
\item adding a new type requires modifying all such code
\item methods will become very long and full of details
\end{itemize}

Send messages instead


\begin{center}
\includegraphics[width=0.6\textwidth]{figures/antifIfCampaign.png}\end{center}

\end{frame}



\begin{frame}[fragile]

\frametitle{Anti If Campaign}

\begin{listing}{}
Dog >> showHappiness
   self shakeTail
Duck >> showHappiness
   self quack
Cat >> showHappiness
   ...
\end{listing}

Branching (with \code{if}) based on the type of an object is bad

\begin{itemize}
\item adding a new type requires modifying all such code
\item methods will become very long and full of details
\end{itemize}

Send messages instead


\begin{center}
\includegraphics[width=0.6\textwidth]{figures/antifIfCampaign.png}\end{center}

\end{frame}



\begin{frame}[fragile]

\frametitle{Do Not Return Nil}

\begin{listing}{}
Inferencer >> rulesForFact: aFact
   self noRule ifTrue: [ ^ nil ]
   ^ self rulesAppliedTo: aFact
\end{listing}

\code{ifTrue: {[} \string^ nil {]}} forces every client to check for \code{nil}:

\begin{listing}{}
(inferencer rulesForFact: 'a')
   ifNotNil: [ :rules |
      rules do: [ :each | ... ]
\end{listing}
\end{frame}



\begin{frame}[fragile]

\frametitle{Return Polymorphic Objects}

When possible, replace \code{if} by polymorphic objects:

\begin{itemize}
\item when returning a collection, return an empty one
\item when returning a number, return 0
\end{itemize}

\begin{listing}{}
Inferencer >> rulesForFact: aFact
   self noRule ifTrue: [ ^ #() ]
   ^ self rulesAppliedTo: aFact
\end{listing}

Your clients can just iterate and manipulate the returned value

\begin{listing}{}
(inferencer rulesForFact: 'a')
   do: [:each | ... ]
\end{listing}
\end{frame}



\begin{frame}[fragile]

\frametitle{For Exceptional Cases, Use Exceptions}

For exceptional cases, replace \code{nil} by exceptions:

\begin{itemize}
\item avoid error codes because they require \code{if} in clients
\item exceptions may be handled by the client, or the client's client, or ...
\end{itemize}

\begin{listing}{}
FileStream >> nextPutAll: aByteArray
   canWrite ifFalse: [ self cantWriteError ].
   ...
FileStream >> cantWriteError
   (CantWriteError file: file) signal
\end{listing}
\end{frame}



\begin{frame}[fragile]

\frametitle{Initialize Your Object State}

Avoid \code{nil} checks by initializing your variables

\begin{itemize}
\item by default instance variables are initialized with \code{nil}
\end{itemize}

\begin{listing}{}
Archive >> initialize
   super initialize.
   members := OrderedCollection new
\end{listing}
\end{frame}



\begin{frame}[fragile]

\frametitle{Use Lazy Initialization if Necessary}

You can defer initialization of a variable to its first use:

\begin{listing}{}
FreeTypeFont >> descent
   ^ cachedDescent ifNil: [
        cachedDescent := (self face descender * self pixelSize //
                               self face unitsPerEm) negated ]
\end{listing}
\end{frame}



\begin{frame}[fragile]

\frametitle{Sometimes you have to check...}

Sometimes you have to check before doing an action

\begin{itemize}
\item if you can, turn the default case into an object
\end{itemize}

\begin{listing}{}
ToolPalette >> nextAction
   self selectedTool
      ifNotNil: [ :tool | tool attachHandles ]

ToolPalette >> previousAction
   self selectedTool
      ifNotNil: [ :tool | tool detachHandles ]
\end{listing}
\end{frame}



\begin{frame}[fragile]

\frametitle{Use NullObject}

\begin{listing}{}
NoTool >> attachHandles
   ^ self
NoTool >> detachHandles
   ^ self
\end{listing}

\begin{listing}{}
ToolPalette >> initialize
   self selectedTool: NoTool new
ToolPalette >> nextAction
   self selectedTool attachHandles
ToolPalette >> previousAction
   self selectedTool detachHandles
\end{listing}

\begin{itemize}
\item a null object proposes a polymorphic API and embeds default actions/values
\item Woolf, Bobby (1998). \symbol{34}Null Object\symbol{34}. In Pattern Languages of Program Design 3. Addison-Wesley.
\end{itemize}
\end{frame}



\begin{frame}[fragile]

\frametitle{Conclusion}

\begin{itemize}
\item A message acts as a better \code{if}
\item Avoid null checks, return polymorphic objects instead
\item Initialize your variables
\item If you can, create objects representing default behavior
\end{itemize}


\begin{center}
\includegraphics[width=0.6\textwidth]{figures/antifIfCampaign.png}\end{center}

\end{frame}




% \setlength{\textwidth}{\originaltextwidth}
\setbeamertemplate{background canvas}{\insertBorderForHandout}

\begin{frame}[plain]

\begin{minipage}{\originaltextwidth}
\centering
\large


\vspace{2em}

A course by

\vspace{1em}

\hspace{-20px}\includegraphics[height=32px]{inriaLogo}\hspace{3em}\raisebox{7px}{and}\hspace{3em}\raisebox{-6px}{\includegraphics[height=30px]{logoutop}}

\vspace{2em}

in collaboration with

\vspace{1em}

\includegraphics[height=40px]{unisciellogo}\hskip 1.5em%
\raisebox{5px}{\includegraphics[height=30px]{unitlogo}}\hskip 2em%
\raisebox{8px}{\includegraphics[height=24px]{univLilleLogo}}\hskip 2em%
\raisebox{3px}{\includegraphics[height=29px]{logo-IMT}}\hskip 2em%
\raisebox{1px}{\includegraphics[height=32px]{minesDouaiLogo}}

\vspace{2.5em}

\includegraphics[width=50px]{by-nc-nd} \tiny \hskip 0.5em \raisebox{5px}{Inria 2016}

\medskip

\tiny
Except where otherwise noted, this work is licensed under CC BY-NC-ND 3.0 France

\url{https://creativecommons.org/licenses/by-nc-nd/3.0/fr/} 

\end{minipage}
\end{frame}

\end{document}

%%% Local Variables:
%%% mode: latex
%%% TeX-master: t
%%% End:
