ADR-002 - Abstraction de Base de Données
ADR-002: Abstraction de Base de Données
Section intitulée « ADR-002: Abstraction de Base de Données »Enregistrement de Décision Architecturale pour le modèle d’accès à la base de données orienté objet de XOOPS.
Accepté - Modèle principal depuis XOOPS 2.0
Contexte
Section intitulée « Contexte »XOOPS avait besoin d’une stratégie d’interaction de base de données qui :
- Abstraire la syntaxe SQL spécifique à la base de données
- Fournir des opérations CRUD cohérentes sur tous les modules
- Activer la désinfection et l’échappement des données automatiques
- Soutenir les futures modifications du moteur de base de données
- Simplifier les opérations courantes pour les développeurs
Les alternatives étaient :
- SQL brut dans tout le code
- ORM complet (Doctrine, Eloquent)
- Abstraction personnalisée légère
Diagramme de Décision
Section intitulée « Diagramme de Décision »graph TB subgraph "Application Layer" A[Module Code] B[Handler Methods] end
subgraph "Abstraction Layer" C[XoopsObjectHandler] D[XoopsPersistableObjectHandler] E[Criteria System] end
subgraph "Database Layer" F[XoopsDatabase] G[MySQLDatabase] H[PDO Wrapper] end
subgraph "Storage" I[(MySQL/MariaDB)] end
A --> B B --> C B --> D C --> E D --> E E --> F F --> G F --> H G --> I H --> IDécision
Section intitulée « Décision »Nous mettrons en œuvre un Modèle de Gestionnaire avec :
1. XoopsObject - Conteneur de Données
Section intitulée « 1. XoopsObject - Conteneur de Données »Chaque entité de données étend XoopsObject :
class Item extends XoopsObject{ public function __construct() { $this->initVar('id', XOBJ_DTYPE_INT, null, false); $this->initVar('title', XOBJ_DTYPE_TXTBOX, '', true, 255); $this->initVar('content', XOBJ_DTYPE_TXTAREA, '', false); $this->initVar('status', XOBJ_DTYPE_INT, 0, false); }}2. Handler - Gestionnaire d’Opérations
Section intitulée « 2. Handler - Gestionnaire d’Opérations »Chaque objet a un gestionnaire correspondant :
class ItemHandler extends XoopsPersistableObjectHandler{ public function __construct($db) { parent::__construct($db, 'mymodule_items', Item::class, 'id', 'title'); }
// CRUD methods inherited: // - create(), get(), insert(), delete() // - getObjects(), getCount(), getAll()}3. Criteria - Constructeur de Requêtes
Section intitulée « 3. Criteria - Constructeur de Requêtes »Conditions de requête orientées objet :
$criteria = new CriteriaCompo();$criteria->add(new Criteria('status', 1));$criteria->add(new Criteria('created', time() - 86400, '>='));$criteria->setSort('created');$criteria->setOrder('DESC');$criteria->setLimit(10);
$items = $handler->getObjects($criteria);Constantes de Type de Données
Section intitulée « Constantes de Type de Données »// Variable types with automatic sanitizationXOBJ_DTYPE_INT // IntegerXOBJ_DTYPE_TXTBOX // Single-line text (escaped)XOBJ_DTYPE_TXTAREA // Multi-line text (escaped)XOBJ_DTYPE_EMAIL // Email validationXOBJ_DTYPE_URL // URL validationXOBJ_DTYPE_ARRAY // Serialized arrayXOBJ_DTYPE_OTHER // No processingXOBJ_DTYPE_FLOAT // Floating pointHéritage du Gestionnaire
Section intitulée « Héritage du Gestionnaire »classDiagram class XoopsObjectHandler { <<abstract>> #db: XoopsDatabase +create(): XoopsObject +get(id): XoopsObject +insert(object): bool +delete(object): bool }
class XoopsPersistableObjectHandler { +getObjects(criteria): array +getCount(criteria): int +getAll(criteria): array +deleteAll(criteria): bool +updateAll(field, value, criteria): bool }
class ItemHandler { +getPublishedItems(): array +getByCategory(catId): array }
XoopsObjectHandler <|-- XoopsPersistableObjectHandler XoopsPersistableObjectHandler <|-- ItemHandlerConséquences
Section intitulée « Conséquences »- Cohérence: Tous les modules utilisent les mêmes modèles
- Sécurité: Échappement automatique empêche l’injection SQL
- Simplicité: Les opérations courantes nécessitent un code minimal
- Maintenabilité: Les modifications apportées à la couche de base de données n’affectent pas les modules
- Testabilité: Les gestionnaires peuvent être mockés pour les tests
- Performance: Surcharge d’abstraction supplémentaire
- Complexité: Courbe d’apprentissage pour les nouveaux développeurs
- Limitations: Les requêtes complexes peuvent nécessiter du SQL brut
- N+1 Problem: Pas de chargement impatient intégré
Atténuations
Section intitulée « Atténuations »- Performance: Mettez en cache les objets fréquemment consultés
- Requêtes Complexes: Autoriser le SQL brut si nécessaire
- N+1: Utilisez getAll() avec les critères appropriés
Évolution vers XOOPS 4.0
Section intitulée « Évolution vers XOOPS 4.0 »flowchart LR subgraph "Current (2.5.x)" A[XoopsDatabase] B[Handlers] C[Criteria] end
subgraph "Future (4.0.x)" D[PDO/DBAL] E[Repository Pattern] F[Query Builder] G[DI Container] end
A --> D B --> E C --> F D --> G E --> GPlans de XOOPS 4.0 :
- Doctrine DBAL pour l’abstraction de base de données
- Modèle de référentiel remplaçant les gestionnaires
- Constructeur de requêtes pour les requêtes complexes
- Intégration complète du conteneur PSR-11
Exemples de Code
Section intitulée « Exemples de Code »CRUD Basique
Section intitulée « CRUD Basique »$helper = Helper::getInstance();$handler = $helper->getHandler('Item');
// Create$item = $handler->create();$item->setVar('title', 'New Item');$handler->insert($item);
// Read$item = $handler->get($id);$title = $item->getVar('title');
// Update$item->setVar('title', 'Updated Title');$handler->insert($item);
// Delete$handler->delete($item);Requête Complexe
Section intitulée « Requête Complexe »$criteria = new CriteriaCompo();$criteria->add(new Criteria('status', 'published'));$criteria->add(new Criteria('category_id', '(1,2,3)', 'IN'));$criteria->add(new Criteria('created', strtotime('-30 days'), '>='));$criteria->setSort('views');$criteria->setOrder('DESC');$criteria->setLimit(10);$criteria->setStart(0);
$items = $handler->getObjects($criteria);$total = $handler->getCount($criteria);Décisions Connexes
Section intitulée « Décisions Connexes »- ADR-001: Architecture Modulaire
- ADR-003: Moteur de Modèles Smarty
Références
Section intitulée « Références »- Martin Fowler - Patterns of Enterprise Application Architecture
- Concepts de Domain-Driven Design
- Modèles Active Record vs Data Mapper
#xoops #architecture #adr #database #handler #design-decision