Modéliser le carnet et ses règles
Objectif : Décrire les contacts et leurs règles métier sans dépendre de PDO ni du protocole HTTP.
Un carnet peut afficher et enregistrer des contacts tout en acceptant des données incohérentes : un nom vide, une adresse électronique mal formée ou un téléphone composé uniquement d’espaces. Ces erreurs ne devraient pas dépendre de la page qui reçoit le formulaire. Vous allez définir les règles qui rendent un contact valide, puis les appliquer dans le service métier, sans faire appel à HTTP ni à la base de données.
Comme vous l’avez vu dans la leçon sur les responsabilités des couches, le service métier ne prend pas en charge le protocole HTTP et le dépôt ne porte pas les règles du carnet. Ici, le contact est représenté par un tableau associatif validé : le contrat du projet n’autorise pas l’ajout d’une classe Contact. Cette représentation permet de fixer les informations attendues sans introduire un nouveau type de classe dans le projet.
Définir les données et les invariants
Un contact comprend ici un identifiant positif, un nom non vide, un courriel valide et un téléphone facultatif. Un invariant métier est une condition qui doit rester vraie pour chaque contact accepté, quel que soit le parcours qui l’a produit. Par exemple, retirer les espaces au début et à la fin d’un nom ne doit pas permettre d’enregistrer un nom vide.
Le courriel est lui aussi nettoyé avant validation. Le téléphone, facultatif, devient une chaîne vide s’il ne contient que des espaces. Ces choix définissent une forme canonique des données : les composants suivants reçoivent des valeurs normalisées plutôt que plusieurs variantes équivalentes. Le service n’a pas à savoir si ces valeurs viennent d’un formulaire, d’une tâche planifiée ou d’un autre appel interne.
Appliquer les règles dans le service métier
Le code suivant est un fichier PHP complet et autonome, à placer temporairement dans un fichier tel que ContactService.php pour examiner le comportement. Il utilise la classe autorisée ContactService et ne crée ni accès PDO, ni lecture de requête HTTP. Les exceptions signalent une donnée invalide à l’appelant ; le service n’affiche rien et ne choisit pas de réponse HTTP.
<?php
declare(strict_types=1);
final class ContactService
{
/**
* @return array{id: int, nom: string, courriel: string, telephone: string}
*/
public function creerContact(
int $id,
string $nom,
string $courriel,
string $telephone = ''
): array {
$nom = trim($nom);
$courriel = trim($courriel);
$telephone = trim($telephone);
if ($id < 1) {
throw new InvalidArgumentException('L’identifiant doit être positif.');
}
if ($nom === '') {
throw new InvalidArgumentException('Le nom est obligatoire.');
}
if (filter_var($courriel, FILTER_VALIDATE_EMAIL) === false) {
throw new InvalidArgumentException('Le courriel est invalide.');
}
return [
'id' => $id,
'nom' => $nom,
'courriel' => $courriel,
'telephone' => $telephone,
];
}
}
$service = new ContactService();
$contact = $service->creerContact(
12,
' Ada Lovelace ',
' [email protected] ',
' '
);
print_r($contact);
try {
$service->creerContact(13, ' ', 'invalide');
} catch (InvalidArgumentException $exception) {
echo $exception->getMessage(), PHP_EOL;
}Array
(
[id] => 12
[nom] => Ada Lovelace
[courriel] => [email protected]
[telephone] =>
)
Le nom est obligatoire.Le résultat montre que les espaces superflus sont retirés et que le téléphone facultatif est conservé sous forme de chaîne vide. Le second appel échoue sur le nom vide ; il ne produit donc aucun contact. Pour vérifier le courriel séparément, transmettez un nom non vide : l’appel lèvera alors l’exception « Le courriel est invalide. ». Chaque règle est ainsi lisible et peut être exercée sans créer de connexion à une base de données.
Des valeurs validées, sans dépendance technique
Un objet de valeur est un type qui représente une valeur métier et porte les règles qui la rendent valide, par exemple une adresse électronique. Le contrat du projet ne permet pas ici d’ajouter une classe dédiée à cette valeur ; la validation et la normalisation restent donc dans le service autorisé. Dans une évolution qui autoriserait de tels types, cette règle pourrait être isolée sans modifier les responsabilités du contrôleur ou du dépôt.
L’identifiant est inclus dans la représentation pour illustrer un contact déjà identifié, mais sa création réelle relèvera du parcours d’ajout et de la persistance. Cette leçon ne décide ni comment attribuer cet identifiant ni comment enregistrer les données. Elle fixe seulement les conditions d’acceptation des informations métier ; les contrats entre composants seront traités dans la leçon suivante.
À retenir
- Un contact valide respecte des invariants métier, quel que soit le parcours d’entrée.
- Le service normalise les valeurs puis refuse celles qui ne respectent pas les règles.
- La validation métier ne dépend ni de PDO ni du protocole HTTP.
- Le modèle reste conforme aux classes autorisées du projet.
Dans la prochaine leçon, vous décrirez les dépendances de persistance derrière un contrat explicite.