Un seul contexte par fonction

Une fonction ne devrait faire qu'une seule et unique chose à la fois.

Ce principe est plein de bon sens, à l'instar du principe de responsabilité unique, mais pourrait vous amener à restreindre arbitrairement la taille de vos fonctions.

Limiter la taille d'une fonction sera bien souvent une chose bénéfique, vous diminuerez probablement ses responsabilités ainsi que sa complexité.

Cependant, plus qu'un volume, il sera intéressant de distinguer les fonctions représentant des intentions de celles représentant des implémentations.

Une fonction décrivant les intentions représente le "quoi" alors qu'une fonction décrivant une implémentation contient le "comment".

Par exemple, la fonction suivante contient une intention, celle d'envoyer un mail de bienvenue au nouveaux utilisateurs :

function sendWelcomeEmailToNewcomersUsers()
{
    $users = $this->getNewcomersUsers();
    $mails = $this->retrieveUsersEmails($users);
    $this->welcomeEmail($emails);
}

Alors que cette fonction contient une implémentation, celle de calculer les emails d'une liste d'utilisateurs :

function retrieveUsersEmails(array $users): array
{
    $emails = [];
    foreach($users as $user)
    {
        $emails[] = $user->email;
    }
    return $emails;
}

La limite entre intentions et implémentations peut parfois sembler fine, pour la distinguer, il sera intéressant de réfléchir en termes de niveau d'abstraction.

Instancier une classe, la manipuler, appeler d'autres fonctions sont des concepts de haut niveau d'abstraction.

En revanche, effectuer des opérations, des boucles, concaténer et accéder à des propriétés de classes sont des concepts de plus bas niveau.

Restreignez vos fonctions à un seul niveau d'abstraction et vous délimiterez naturellement les fonctions contenant des intentions de celles contenant des implémentations.

La taille d'une fonction sera moins importante dès lors que vous ne mélangerez plus les contextes et les niveaux d'abstraction.

Cette séparation par contexte devrait vous amener à écrire une multitude de petites fonctions, n'ayez crainte, écrire des fonctions de quelques lignes n'est pas une problématique, elles représentent chacune une petite brique de votre application.

Pour finir, gardez en tête que si vous pouvez extraire une ligne d'une fonction, c'est probablement parce que cette dernière fait plusieurs choses.

If code requires effort to understand, extract it into a function named after its purpose.