Bibliobrol : le DAO
Nous pouvons utiliser une base de données MS Access pour stocker les informations de notre application.
Ce choix présente deux avantages majeurs :
- Les pilotes de la base de données sont normalement pris en charge par le système d'exploitation, même si la machine sur laquelle nous exécutons l'application n'est pas pourvue du logiciel MS Access. En effet, nous pouvons accéder à une base de données Access (le fichier portant l'extension .mdb) sans utiliser le logiciel Access.
- Si nous utilisons un chemin relatif vers la base de données, l'application et la base de données peuvent se trouver sur un support de stockage amovible (disque dur externe, memory stick, lecteur mp3, etc.).
Si nous désirons partager une base de données en réseau, il nous faudra placer la base de données sur un répertoire partagé, et nous pourrons alors accéder simultanément aux données.
Le problème de ce genre de situation est qu'Access n'est pas le type de base de données idéal pour une utilisation simultanée par un grand nombre d'utilisateurs.
Nous pouvons résoudre certains problèmes en verrouillant les données accédées en modification pour gérer les accès concurrents, mais si l'application doit supporter un nombre d'utilisateurs simultané important il vaut mieux se tourner vers d'autres systèmes de gestion de bases de données (SGBD).
De plus, si un nouveau SGBD arrive sur le marché et est plus performant, nous ne désirons certainement pas recoder toute l'application.
Nous devons en outre prendre en compte la maintenance du code de l'application.
Pour toutes ces raisons, les accès au système de persistance doivent à tout prix être groupés et séparés du reste du code. Ni la vue, ni le modèle ne doivent savoir quel est le type de persistance employé. Il est dès lors tout à fait impensable d'accéder directement à une base de données depuis la vue (une fenêtre par exemple) ou le modèle propre (par exemple, un objet Ouvrage peut posséder la méthode sauverOuvrage(), mais ne connaît pas le système employé pour la sauvegarde).
Découplage du DAO
Comment rendre le code de notre application de gestion de media indépendant du système de persistance ?
Nous allons créer une classe abstraite DAOFactory. Lorsque nous nous adressons à cette classe, nous en utilisons en réalité une de ses implémentations concrètes. De cette manière, nous n'avons pas besoin de savoir à quelle classe concrète nous nous adressons.
Dans le cas de cet exemple, nous pouvons mettre en œuvre le pattern Singleton pour être certain de toujours travailler avec la même instance. Le constructeur (dont l'accès est réduit afin d'éviter d'instancier un nouvel objet) lit le fichier de configuration pour déterminer quel système de persistance utiliser, puis retourne un objet du type de persistance désiré.
Nous pouvons estimer gràce aux grasp patterns que c'est à cette classe que revient la responsabilité de déterminer quels sont les types de persistances disponibles. Nous maintiendrons donc cette information sous la forme d'une énumération (voir les énumérations en Java, ou les énumérations en C#), afin de nous assurer que les valeurs ne puissent être malencontreusement modifiées.
Nous avons vu que notre modèle contenait un certain nombre de classes, mais nous devons pouvoir stocker ces valeurs dans un système persistant. Nous allons donc créer une interface correspondant à chaque classe que nous désirons stocker dans notre persistance.
Nous devons donc déclarer dans notre classe abstraite DAOFactory des méthodes abstraites qui nous permettront d'accéder aux différentes implémentations de ces interfaces en fonction du système de persistance utilisé.
Les différentes interfaces définissent les méthodes auxquelles nous devons avoir accès.
Code c# (DAOFactory.cs) (71 lignes)
using be.gaudry.bibliobrol.config; using be.gaudry.bibliobrol.model.enums; using be.gaudry.bibliobrol.model.dao.config; namespace be.gaudry.bibliobrol.model.dao { /// <summary> /// Provides concrete persistence classes for the persistent type defined in the user settings /// </summary> public abstract class DAOFactory { #region singleton protected static DAOFactory instance = null; protected DAOFactory() { } /// <summary> /// Get unique instance of <code>DAOFactory</code> providing methods to access to the persistent layer. /// </summary> public static DAOFactory Instance { get { lock (threadLockObject) { if (instance == null) { resetDAO(); } return instance; } } } /// <summary> /// Resets unique instance of <code>DAOFactory</code> to use another persistent layer.<br /> /// <b><u>Be extremly carefull with using this method :</u></b> if application is not restarted, /// inconsistent data between old persistent layer /// and new persistent layer will crash the application and the persistent storage. /// </summary> public static void resetDAO() { PERSISTENCE_TYPE persistentType = Config.PersistentType; switch (persistentType) { //case PERSISTENCE_TYPE.SQLExpress: //case PERSISTENCE_TYPE.MySQL: // instance = new mysql.MySQLFactory(); // break; //case PERSISTENCE_TYPE.Access: default: break; } } #endregion #region getDao methods to implement public abstract AbstractDBConfig getDBConfig(); public abstract IConfigDao getConfigDao(); public abstract IPersonDao getPersonDao(); public abstract IBrolDao getBrolDao(); public abstract IMediaBrolDao getMediaBrolDao(); public abstract ITaskDao getTaskDao(); public abstract IExporterDao getExporterDao(); public abstract IImporterDao getImporterDao(); public abstract IStatsDao getStatsDao(); public abstract ISerieDao getSerieDao(); #endregion } }
Remarque
Nous ne sommes pas obligés de strictement créer une interface par classe dont nous assurons le stockage. Nous pouvons par exemple grouper certaines notions dans une même interface si cette opération n'altère pas la compréhension et la maintenance du code.
English translation
You have asked to visit this site in English. For now, only the interface is translated, but not all the content yet.If you want to help me in translations, your contribution is welcome. All you need to do is register on the site, and send me a message asking me to add you to the group of translators, which will give you the opportunity to translate the pages you want. A link at the bottom of each translated page indicates that you are the translator, and has a link to your profile.
Thank you in advance.
Document created the 06/12/2006, last modified the 26/10/2018
Source of the printed document:https://www.gaudry.be/en/bibliobrol-dao.html
The infobrol is a personal site whose content is my sole responsibility. The text is available under CreativeCommons license (BY-NC-SA). More info on the terms of use and the author.
References
These references and links indicate documents consulted during the writing of this page, or which may provide additional information, but the authors of these sources can not be held responsible for the content of this page.
The author This site is solely responsible for the way in which the various concepts, and the freedoms that are taken with the reference works, are presented here. Remember that you must cross multiple source information to reduce the risk of errors.