Métier isolé
Les règles métier écrites en PHP pur, sans dépendance au framework ni à la base. Tests exécutés en millisecondes.
- Objets métier riches
- Règles protégées
- Indépendant du framework
- Événements métier
Une architecture où le métier est isolé du framework et de la base de données, appliquée avec pragmatisme. Un noyau métier indépendant des détails techniques, des tests rapides, des montées de version fluides — l'approche que j'utilise sur tous les projets dont la durée de vie dépasse 3 ans.
Les règles métier écrites en PHP pur, sans dépendance au framework ni à la base. Tests exécutés en millisecondes.
Les cas d'usage (passer commande, annuler, facturer) sont coordonnés sans mélanger de règles métier. Chaque action est transactionnelle.
Le métier déclare ce dont il a besoin (« envoyer un email », « sauvegarder une commande ») ; la technique (base, API externe, fichier) se branche sans toucher au métier.
Composants immuables, assemblage par Symfony. Composition plutôt qu'héritage : chaque classe fait une seule chose, bien.
Le métier se teste sans lancer le framework, sans base. La suite complète tourne en moins de 30 secondes sur un projet moyen.
Chaque décision structurante (choix d'approche, dépendance introduite, compromis accepté) est consignée dans un document versionné, lisible par un futur repreneur.
<?php
declare(strict_types=1);
namespace App\Domain\Order;
// Entité riche : les invariants métier sont protégés par le constructeur
// et les méthodes de transition d'état. Aucune annotation Doctrine.
final class Order
{
/** @var list<OrderItem> */
private array $items;
private function __construct(
private readonly OrderId $id,
private readonly CustomerId $customerId,
array $items,
private OrderStatus $status,
) {
if ($items === []) {
throw new EmptyOrder();
}
$this->items = $items;
}
/** @param list<OrderItem> $items */
public static function place(CustomerId $customer, array $items): self
{
return new self(OrderId::generate(), $customer, $items, OrderStatus::Placed);
}
public function confirm(): void
{
if ($this->status !== OrderStatus::Placed) {
throw new InvalidTransition($this->status, 'confirm');
}
$this->status = OrderStatus::Confirmed;
}
}
Une commande, écrite uniquement en PHP pur : aucune dépendance au framework, aucune référence à la base. Les règles métier vivent ici et nulle part ailleurs.
Pour poser les fondations : périmètres métier, règles, décisions d'architecture. Livrable : squelette de code + documentation.
Introduction de la nouvelle architecture dans une base existante, module par module, sans geler votre activité.
Coaching architectural régulier : revue de code, programmation en binôme, montée en compétence de vos développeurs.
Tarifs sur devis après cadrage · forfait ou régie selon le format
Plateforme de gestion de 3 000+ biens, refondue avec un métier isolé du framework. Quatre ans plus tard, zéro régression métier lors des montées Symfony et ajout de fonctionnalités sans casser les anciennes.
Pour une application simple, oui. Pour une application métier avec règles complexes, intégrations multiples, durée de vie de plus de 3 ans, c'est un investissement qui rembourse plusieurs fois. On en discute projet par projet.
L'outillage Symfony pour la plomberie (configuration, routes, assemblage). Fait-main pour l'organisation métier — les générateurs automatiques produisent un squelette qui mélange tout.
Très bien, à condition de la cantonner à la couche technique. Les objets métier ne contiennent aucune référence à Doctrine — la correspondance avec la base se fait séparément.
Une transaction englobe chaque cas d'usage côté applicatif. Les événements métier (facture créée, commande confirmée) sont publiés seulement après validation réussie, jamais entre-temps.
Non. L'approche métier isolé sur tous les projets. La séparation lecture/écriture seulement quand les deux usages divergent fortement. La traçabilité complète des événements uniquement quand le métier l'exige (audit, historique).
Les tests métier : non. Les tests applicatifs : non (doubles en mémoire). Les tests d'intégration sur la vraie base : oui, mais c'est une minorité et on les isole.
Un appel, pas un formulaire de 12 champs. Vous m'expliquez votre besoin, je vous dis honnêtement si je suis la bonne personne, on repart avec une prochaine étape claire.