Aller au contenu

Modèle Service Layer dans XOOPS

2.5.x ✅ 4.0.x ✅

Le modèle Service Layer encapsule la logique métier dans des classes de service dédiées, fournissant une séparation claire entre les contrôleurs et les couches d’accès aux données. Ce modèle promeut la réutilisabilité du code, la testabilité et la maintenabilité.

Le Service Layer :

  • Contient la logique métier du domaine
  • Coordonne plusieurs dépôts
  • Gère les opérations complexes
  • Gère les transactions
  • Effectue la validation et l’autorisation
  • Fournit des opérations de haut niveau aux contrôleurs
  • Logique métier réutilisable sur plusieurs contrôleurs
  • Facile à tester isolément
  • Implémentation centralisée des règles métier
  • Séparation claire des préoccupations
  • Code de contrôleur simplifié
<?php
// Service avec dépendances injectées
class UserService
{
private $userRepository;
private $emailService;
public function __construct(
UserRepositoryInterface $userRepository,
EmailServiceInterface $emailService
) {
$this->userRepository = $userRepository;
$this->emailService = $emailService;
}
public function registerUser($username, $email, $password)
{
// Valider
$this->validate($username, $email, $password);
// Créer l'utilisateur
$user = new User();
$user->setUsername($username);
$user->setEmail($email);
$user->setPassword($password);
// Enregistrer
$userId = $this->userRepository->save($user);
// Envoyer un e-mail de bienvenue
$this->emailService->sendWelcome($email, $username);
return $userId;
}
private function validate($username, $email, $password)
{
$errors = [];
if (strlen($username) < 3) {
$errors['username'] = 'Username too short';
}
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$errors['email'] = 'Invalid email';
}
if (strlen($password) < 6) {
$errors['password'] = 'Password too short';
}
if (!empty($errors)) {
throw new ValidationException('Invalid input', $errors);
}
}
}
?>
<?php
class ServiceContainer
{
private $services = [];
public function __construct($db)
{
// Enregistrer les dépôts
$this->services['userRepository'] = new UserRepository($db);
// Enregistrer les services
$this->services['userService'] = new UserService(
$this->services['userRepository']
);
}
public function get($name)
{
if (!isset($this->services[$name])) {
throw new \InvalidArgumentException("Service not found: $name");
}
return $this->services[$name];
}
}
?>
<?php
class UserController
{
private $userService;
public function __construct(ServiceContainer $container)
{
$this->userService = $container->get('userService');
}
public function registerAction()
{
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
return [];
}
try {
$userId = $this->userService->registerUser(
$_POST['username'],
$_POST['email'],
$_POST['password']
);
return [
'success' => true,
'userId' => $userId,
];
} catch (ValidationException $e) {
return [
'success' => false,
'errors' => $e->getErrors(),
];
}
}
}
?>
  • Chaque service gère une seule préoccupation du domaine
  • Les services dépendent des interfaces, pas des implémentations
  • Utilisez l’injection de constructeur pour les dépendances
  • Les services doivent être testables isolément
  • Lancez des exceptions spécifiques au domaine
  • Les services ne doivent pas dépendre des détails de la demande HTTP
  • Gardez les services concentrés et cohésifs

Voir aussi :


Tags: #service-layer #business-logic #dependency-injection #design-patterns