🎯 Le Contexte & L'Objectif

Alexandria — en référence à la célèbre bibliothèque d'Alexandrie — est née d'un projet universitaire en semestre 6 à l'ESIGELEC. Le cahier des charges était clair : concevoir une application capable de gérer l'intégralité du cycle de vie d'une bibliothèque, depuis le catalogue des ouvrages jusqu'au suivi des prêts par usager.
L'application devait prendre en charge cinq entités métier — usagers, livres, auteurs, genres et prêts — avec pour chacune les opérations classiques de création, consultation, modification et suppression. Les données devaient être persistées dans une base Oracle fournie par l'école, et l'ensemble des interactions tracé dans un fichier de log horodaté. Enfin, le projet exigeait la génération d'un fichier de résultats statistiques ainsi qu'une requête personnalisée affichée directement dans l'interface.
Plutôt que de me limiter au strict minimum, j'ai fait le choix de développer une interface graphique complète en Java Swing, en allant au-delà du cahier des charges sur plusieurs aspects : gestion des prêts en bonus, sécurisation des entrées, composants réutilisables et architecture pensée pour être maintenable.
🛠️ Ma Contribution & Mon Rôle
J'ai réalisé ce projet intégralement seul, de la modélisation de la base de données jusqu'à l'interface utilisateur finale.



- Modélisation et base de données : conception du schéma relationnel Oracle, écriture des procédures et fonctions SQL pour les opérations CRUD, et mise en place de
RAISE_APPLICATION_ERRORpour remonter des erreurs métier explicites côté Java. - Couche d'accès aux données (DAO) : implémentation de cinq DAO (Usager, Livre, Auteur, Genre, Prêt) communiquant avec la base via JDBC, avec des jointures optimisées pour éviter les requêtes en cascade.
- Interface graphique Swing : développement de l'ensemble des fenêtres de gestion — listes scrollables, formulaires d'ajout/modification/suppression avec validation, modales de confirmation et vue détaillée par entité (un usager affiche ses prêts en cours, par exemple).
- Architecture UI : mise en place d'un système d'héritage de formulaires (
BaseFormFrame→ObjectForm→ formulaires spécifiques) et de composants réutilisables (ButtonComponent,FormComponent,ListComponent) pour factoriser le code et accélérer le développement. - Fonctionnalités bonus : histogramme du nombre d'usagers par année de naissance (composant
HistogramPanelpeint à la main), génération d'un fichier de résultats statistiques, et système de logging complet via unLogManagersingleton.
💻 Stack Technique
- Langage : Java — imposé par le cadre académique, mais pleinement exploité avec l'héritage, le polymorphisme et les design patterns (DAO, Singleton, Template Method).
- Interface graphique : Swing — la bibliothèque native de Java pour le desktop. Malgré sa réputation de lourdeur, j'ai réussi à obtenir une interface propre et cohérente grâce à un système de composants modulaires.
- Base de données : Oracle (instance de l'ESIGELEC) — accédée via JDBC avec des
PreparedStatementpour se prémunir contre les injections SQL. - Librairies tierces : JDatePicker pour la sélection de dates dans les formulaires, JUnit pour les tests unitaires.
⚙️ Architecture & Défis Techniques





Un système de formulaires génériques par héritage
Le projet gère cinq entités, chacune avec trois opérations (ajout, modification, suppression). Sans précaution, cela représente quinze formulaires quasi identiques avec beaucoup de code dupliqué. Pour éviter cela, j'ai conçu une hiérarchie de classes :
BaseFormFramegère le squelette commun à tout formulaire (layout, boutons, messages d'erreur).- Chaque entité possède une classe
ObjectFormintermédiaire (ex :LivreForm,UsagerForm) qui définit la validation des champs. - Les formulaires concrets (
LivreAddForm,LivreModifyForm,LivreDeleteForm) héritent de leurObjectFormet ne redéfinissent que le strict nécessaire : les champs à afficher et l'action principale.
Ce pattern m'a permis de produire quinze formulaires fonctionnels tout en gardant un code lisible et facilement extensible.
Sécurisation côté SQL et côté Java
Plutôt que de laisser Java gérer seul la validation, j'ai mis en place une double couche de protection :
- Côté Oracle : des procédures stockées avec
RAISE_APPLICATION_ERRORrenvoient des codes et messages d'erreur explicites (ex : tentative de suppression d'un auteur encore référencé par un livre). - Côté Java : les
SQLExceptionsont interceptées et les messages personnalisés sont affichés à l'utilisateur via des popups, avec un fallback sur les erreurs natives Oracle si aucune procédure personnalisée n'est en jeu.
Cette approche garantit que la base de données reste cohérente quoi qu'il arrive, même si l'application venait à être modifiée ou étendue par un autre développeur.
Affichage dynamique des listes
Chaque entité est présentée dans une liste scrollable construite via un composant ListComponent qui génère dynamiquement des lignes avec les données et les boutons d'action (voir, modifier, supprimer). Lors d'un ajout, d'une modification ou d'une suppression, la liste se rafraîchit automatiquement sans rechargement de la fenêtre — un détail qui améliore sensiblement l'expérience utilisateur.
Visualisation de données : l'histogramme


Pour la requête personnalisée demandée par le cahier des charges, j'ai développé un composant HistogramPanel qui dessine un diagramme en barres directement via l'API Graphics de Java. L'histogramme affiche le nombre d'usagers par année de naissance, avec des barres dimensionnées dynamiquement et des labels lisibles. Ce composant est entièrement peint à la main, sans librairie de graphiques externe.
🚀 Résultats & Impact
- Couverture fonctionnelle : les cinq entités sont entièrement gérables via l'interface, avec toutes les opérations CRUD et les vues détaillées associées.
- Au-delà du cahier des charges : la gestion des prêts (ajout bonus), l'histogramme personnalisé, la protection contre les injections SQL et le système de composants réutilisables dépassent les exigences initiales du projet.
- Traçabilité : chaque action utilisateur est enregistrée dans un fichier de log horodaté, conformément aux spécifications.
- Robustesse : la validation des entrées côté Java et les procédures SQL sécurisées empêchent les états incohérents dans la base de données.
- Note obtenue : 20/20 — le projet a été évalué sur la qualité du code, le respect du cahier des charges et les fonctionnalités bonus apportées.
💡 Ce que j'ai appris
Ce projet a été ma première vraie confrontation avec Swing, et je comprends maintenant pourquoi le framework a la réputation d'être fastidieux. La création de composants graphiques demande beaucoup de code boilerplate, et le positionnement des éléments via GridBagLayout n'est pas toujours intuitif. Malgré cela, le fait de tout construire à la main m'a donné une compréhension solide du fonctionnement interne d'une interface graphique : gestion des événements, cycles de rendu, imbrication de panels.
Si c'était à refaire, plusieurs améliorations s'imposeraient :
- Singletoniser la connexion : actuellement, chaque DAO instancie sa propre connexion à la base, ce qui est inutilement coûteux.
- Améliorer l'UX des formulaires : ne pas fermer la fenêtre après une erreur de saisie, et ajouter des boutons "Retour" plutôt que de forcer l'utilisateur à utiliser la croix.
- Étendre les tests : la couverture JUnit est minimale et mériterait d'être renforcée, notamment sur la couche DAO.
- Généraliser davantage l'architecture UI : le pattern d'héritage des formulaires pourrait être poussé plus loin pour réduire encore la duplication entre les entités.