Menu
Coddy logo textTech

Patron Dépôt

Fait partie de la section Programmation Orientée Objet du Journey PHP de Coddy. Leçon 81 sur 91.

Le Repository Pattern est un modèle de conception qui sert d’intermédiaire entre la logique métier de votre application et le stockage des données. Il fournit une interface semblable à une collection pour accéder aux objets du domaine, en masquant les détails de la manière dont les données sont réellement stockées ou récupérées.

Considérez un dépôt comme une collection spécialisée qui sait comment persister et récupérer des objets. Le code de votre application demande au dépôt un utilisateur par son ID ou enregistre un nouveau produit, sans savoir si les données se trouvent dans une base de données, un fichier ou une API. Cette séparation rend votre code plus facile à tester et plus flexible.

<?php
interface UserRepositoryInterface {
    public function find(int $id): ?User;
    public function findAll(): array;
    public function save(User $user): void;
    public function delete(int $id): void;
}

class User {
    public function __construct(
        public int $id,
        public string $name,
        public string $email
    ) {}
}

L’implémentation du dépôt gère le mécanisme de stockage réel :

<?php
class InMemoryUserRepository implements UserRepositoryInterface {
    private array $users = [];
    
    public function find(int $id): ?User {
        return $this->users[$id] ?? null;
    }
    
    public function findAll(): array {
        return array_values($this->users);
    }
    
    public function save(User $user): void {
        $this->users[$user->id] = $user;
    }
    
    public function delete(int $id): void {
        unset($this->users[$id]);
    }
}

$repo = new InMemoryUserRepository();
$repo->save(new User(1, "Alice", "alice@example.com"));
$repo->save(new User(2, "Bob", "bob@example.com"));

echo $repo->find(1)->name . "\n";
echo count($repo->findAll());

Sortie :

Alice
2

L’intérêt de ce modèle est que vous pouvez remplacer les implémentations sans modifier votre logique métier. Vous devez passer d’un stockage en mémoire à une base de données ? Créez une nouvelle classe de dépôt qui implémente la même interface. Le code de votre application reste intact, car il dépend de l’interface, et non de l’implémentation concrète.

challenge icon

Défi

Facile

Construisons un système d’inventaire de produits à l’aide du modèle Repository. Vous créerez une séparation claire entre vos objets de domaine et la manière dont ils sont stockés, ce qui permettra au code de votre application de travailler avec des produits sans connaître les détails du stockage.

Vous organiserez votre code sur quatre fichiers :

  • Product.php : créez une classe Product représentant les articles de votre inventaire. Chaque produit possède un id (int), un name (string) et un price (float). Utilisez la promotion des propriétés du constructeur avec des propriétés publiques pour faciliter l’accès.
  • ProductRepositoryInterface.php : définissez une interface ProductRepositoryInterface qui établit le contrat pour toute implémentation de stockage de produits. Votre interface doit déclarer les méthodes suivantes :
    • find(int $id): ?Product : récupère un produit par son ID, ou null s’il est introuvable
    • findAll(): array : récupère tous les produits sous forme de tableau
    • save(Product $product): void : enregistre ou met à jour un produit
    • delete(int $id): void : supprime un produit par son ID
  • InMemoryProductRepository.php : incluez à la fois la classe Product et l’interface. Créez une classe InMemoryProductRepository qui implémente l’interface en utilisant un tableau privé pour stocker les produits. Les produits doivent être indexés par leur ID pour permettre une recherche efficace. La méthode findAll() doit retourner uniquement les objets produits (utilisez array_values() pour réinitialiser les clés du tableau).
  • main.php : incluez le fichier du dépôt. Vous recevrez deux entrées : d’abord une chaîne JSON contenant les produits à ajouter, puis, sur une ligne distincte, l’ID entier à rechercher.

    Le format JSON sera le suivant :

    [{"id": 1, "name": "Laptop", "price": 999.99}, {"id": 2, "name": "Mouse", "price": 29.99}]

    Créez un InMemoryProductRepository, enregistrez tous les produits provenant de l’entrée JSON, puis utilisez la deuxième entrée (l’ID) pour trouver un produit spécifique. Affichez les résultats dans ce format :

    Total products: [count]
    Found: [name] - $[price]

    Formatez le prix avec deux décimales. Si le produit est introuvable, affichez plutôt Found: Not found.

Le modèle Repository est particulièrement utile lorsque vous devez remplacer des implémentations de stockage. Votre code principal dépend uniquement de l’interface : passer d’un stockage en mémoire à une base de données consisterait à créer une nouvelle classe de dépôt sans modifier la logique de l’application.

Essayez vous-même

<?php

require_once 'InMemoryProductRepository.php';

// Lire l'entrée
$jsonInput = trim(fgets(STDIN));
$searchId = intval(trim(fgets(STDIN)));

// Analyser l'entrée JSON en un tableau
$productsData = (array)json_decode($jsonInput, true);

// TODO: Créer une instance de InMemoryProductRepository

// TODO: Parcourir $productsData et enregistrer chaque produit
// Chaque élément a les clés 'id', 'name' et 'price'

// TODO: Récupérer tous les produits et afficher le nombre total
// Format: "Total products: [count]"

// TODO: Trouver le produit avec $searchId
// Si trouvé, afficher : "Found: [name] - $[price]" (prix formaté à 2 décimales)
// If not found, print: "Found: Not found"

?>
quiz iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Programmation Orientée Objet

Entraînez-vous par vous-même : Compilateur PHP en ligne