OOAD - Stratégies de mise en œuvre

La mise en œuvre d'une conception orientée objet implique généralement l'utilisation d'un langage de programmation orienté objet (OOPL) standard ou le mappage de conceptions d'objets sur des bases de données. Dans la plupart des cas, cela implique les deux.

Implémentation à l'aide de langages de programmation

Habituellement, la tâche de transformer une conception d'objet en code est un processus simple. Tout langage de programmation orienté objet comme C ++, Java, Smalltalk, C # et Python, inclut des dispositions pour représenter des classes. Dans ce chapitre, nous illustrons le concept en utilisant C ++.

La figure suivante montre la représentation de la classe Circle à l'aide de C ++.

Association de mise en œuvre

La plupart des langages de programmation ne fournissent pas de constructions pour implémenter directement des associations. La tâche de mise en place des associations nécessite donc une réflexion approfondie.

Les associations peuvent être unidirectionnelles ou bidirectionnelles. En outre, chaque association peut être un à un, un à plusieurs ou plusieurs à plusieurs.

Associations unidirectionnelles

Pour la mise en œuvre d'associations unidirectionnelles, il faut prendre soin de conserver l'unidirectionnalité. Les implémentations pour différentes multiplicité sont les suivantes -

  • Optional Associations- Ici, un lien peut ou non exister entre les objets participants. Par exemple, dans l'association entre le client et le compte courant dans la figure ci-dessous, un client peut ou non avoir un compte courant.

Pour l'implémentation, un objet de compte courant est inclus en tant qu'attribut dans Customer qui peut être NULL. Implémentation en C ++ -

class Customer {
   private:
   // attributes
   Current_Account c; //an object of Current_Account as attribute
   
   public:  

   Customer() {
      c = NULL; 
   } // assign c as NULL

   Current_Account getCurrAc() {
      return c;
   }
   
   void setCurrAc( Current_Account myacc) {
      c = myacc;
   }

   void removeAcc() {  
      c = NULL;
   } 
};
  • One–to–one Associations- Ici, une instance d'une classe est liée à exactement une instance de la classe associée. Par exemple, le service et le gestionnaire ont une association un à un, comme illustré dans la figure ci-dessous.

Ceci est implémenté en incluant dans Department, un objet de Manager qui ne doit pas être NULL. Implémentation en C ++ -

class Department {
   private:
   // attributes
   Manager mgr; //an object of Manager as attribute
   
   public:  
   Department (/*parameters*/, Manager m) { //m is not NULL   
      // assign parameters to variables
      mgr = m;
   } 

   Manager getMgr() {  
      return mgr;  
   }    
};
  • One–to–many Associations- Ici, une instance d'une classe est liée à plusieurs instances de la classe associée. Par exemple, considérez l'association entre l'employé et la personne à charge dans la figure suivante.

Ceci est implémenté en incluant une liste de personnes à charge dans la classe Employee. Implémentation à l'aide du conteneur de liste C ++ STL -

class Employee {
   private:
   char * deptName;
   list <Dependent> dep; //a list of Dependents as attribute

   public:  
   void addDependent ( Dependent d) { 
      dep.push_back(d); 
   } // adds an employee to the department

   void removeDeoendent( Dependent d) { 
      int index = find ( d, dep );
      // find() function returns the index of d in list dep
      dep.erase(index);
   }               
};

Associations bidirectionnelles

Pour mettre en œuvre une association bidirectionnelle, les liens dans les deux sens doivent être maintenus.

  • Optional or one–to–one Associations - Considérez la relation entre le projet et le gestionnaire de projet ayant une association bidirectionnelle un à un comme le montre la figure ci-dessous.

Implémentation en C ++ -

Class Project {
   private:
   // attributes
   Project_Manager pmgr; 
   public:  
   void setManager ( Project_Manager pm);       
   Project_Manager changeManager();   
};

class Project_Manager {
   private:
   // attributes
   Project pj; 

   public:  
   void setProject(Project p);       
   Project removeProject();   
};
  • One–to–many Associations - Considérez la relation entre le ministère et l'employé ayant une association un à plusieurs, comme le montre la figure ci-dessous.

Implémentation à l'aide du conteneur de liste C ++ STL

class Department {
   private:
   char * deptName;
   list <Employee> emp; //a list of Employees as attribute

   public:  
   void addEmployee ( Employee e) { 
      emp.push_back(e); 
   } // adds an employee to the department

   void removeEmployee( Employee e) { 
      int index = find ( e, emp );
      // find function returns the index of e in list emp
      emp.erase(index);
   }               
};

class Employee {
   private:
   //attributes
   Department d;

   public:
   void addDept();
   void removeDept();
};

Implémentation d'associations en tant que classes

Si une association a des attributs associés, elle doit être implémentée en utilisant une classe distincte. Par exemple, considérez l'association un à un entre l'employé et le projet, comme illustré dans la figure ci-dessous.

Implémentation de WorksOn en C ++

class WorksOn {
   private:
   Employee e; 
   Project p;
   Hours h;
   char * date;

   public:
   // class methods
};

Implémentation de contraintes

Les contraintes dans les classes restreignent la plage et le type de valeurs que les attributs peuvent prendre. Afin d'implémenter des contraintes, une valeur par défaut valide est attribuée à l'attribut lorsqu'un objet est instancié à partir de la classe. Chaque fois que la valeur est modifiée lors de l'exécution, il est vérifié si la valeur est valide ou non. Une valeur non valide peut être gérée par une routine de gestion des exceptions ou par d'autres méthodes.

Example

Considérez une classe Employee où l'âge est un attribut qui peut avoir des valeurs comprises entre 18 et 60. Le code C ++ suivant l'incorpore -

class Employee {
   private: char * name;
   int age;
   // other attributes

   public:
   Employee() {                   // default constructor 
      strcpy(name, "");
      age = 18;                // default value
   }
 
   class AgeError {};          // Exception class
   void changeAge( int a) {   // method that changes age 
      if ( a < 18 || a > 60 )  // check for invalid condition
      throw AgeError();        // throw exception
      age = a;			
   }
};

Implémentation des graphiques d'état

Il existe deux stratégies de mise en œuvre alternatives pour implémenter les états dans les diagrammes d'état.

Énumérations dans la classe

Dans cette approche, les états sont représentés par différentes valeurs d'un membre de données (ou d'un ensemble de membres de données). Les valeurs sont explicitement définies par une énumération dans la classe. Les transitions sont représentées par des fonctions membres qui modifient la valeur du membre de données concerné.

Disposition des classes dans une hiérarchie de généralisation

Dans cette approche, les états sont disposés dans une hiérarchie de généralisation de manière à pouvoir être référencés par une variable de pointeur commune. La figure suivante montre une transformation d'un diagramme d'état en une hiérarchie de généralisation.

Mappage d'objets au système de base de données

Persistance des objets

Un aspect important du développement de systèmes orientés objet est la persistance des données. Grâce à la persistance, les objets ont une durée de vie plus longue que le programme qui les a créés. Les données persistantes sont enregistrées sur un support de stockage secondaire à partir duquel elles peuvent être rechargées si nécessaire.

Aperçu du SGBDR

Une base de données est une collection ordonnée de données associées.

Un système de gestion de base de données (SGBD) est un ensemble de logiciels qui facilite les processus de définition, de création, de stockage, de manipulation, de récupération, de partage et de suppression de données dans des bases de données.

Dans les systèmes de gestion de base de données relationnelle (SGBDR), les données sont stockées sous forme de relations ou de tables, où chaque colonne ou champ représente un attribut et chaque ligne ou tuple représente un enregistrement d'une instance.

Chaque ligne est identifiée de manière unique par un ensemble choisi d'attributs minimaux appelés primary key.

UNE foreign key est un attribut qui est la clé primaire d'une table associée.

Représenter les classes sous forme de tableaux dans le SGBDR

Pour mapper une classe à une table de base de données, chaque attribut est représenté comme un champ dans la table. Soit un ou plusieurs attributs existants sont affectés en tant que clé primaire, soit un champ ID distinct est ajouté en tant que clé primaire. La classe peut être partitionnée horizontalement ou verticalement selon les besoins.

Par exemple, la classe Circle peut être convertie en table comme indiqué dans la figure ci-dessous.

Schema for Circle Table: CIRCLE(CID, X_COORD, Y_COORD, RADIUS, COLOR)
Creating a Table Circle using SQL command:
CREATE TABLE CIRCLE (   
   CID	VARCHAR2(4) PRIMARY KEY,
   X_COORD INTEGER NOT NULL,
   Y_COORD INTEGER NOT NULL,
   Z_COORD INTEGER NOT NULL,
   COLOR 
);

Mappage d'associations sur des tables de base de données

Associations un-à-un

Pour implémenter des associations 1: 1, la clé primaire d'une table est affectée comme clé étrangère de l'autre table. Par exemple, considérons l'association entre le service et le gestionnaire -

Commandes SQL pour créer les tables

CREATE TABLE DEPARTMENT ( 
   DEPT_ID INTEGER PRIMARY KEY,
   DNAME VARCHAR2(30) NOT NULL,
   LOCATION VARCHAR2(20),
   EMPID INTEGER REFERENCES MANAGER 
);

CREATE TABLE MANAGER ( 
   EMPID INTEGER PRIMARY KEY,
   ENAME VARCHAR2(50) NOT NULL,
   ADDRESS VARCHAR2(70),
);

Associations un à plusieurs

Pour implémenter des associations 1: N, la clé primaire de la table du côté 1 de l'association est affectée comme clé étrangère de la table du côté N de l'association. Par exemple, considérons l'association entre le ministère et l'employé -

Commandes SQL pour créer les tables

CREATE TABLE DEPARTMENT ( 
   DEPT_ID INTEGER PRIMARY KEY,
   DNAME VARCHAR2(30) NOT NULL,
   LOCATION VARCHAR2(20),
);

CREATE TABLE EMPLOYEE ( 
   EMPID INTEGER PRIMARY KEY,
   ENAME VARCHAR2(50) NOT NULL,
   ADDRESS VARCHAR2(70),
   D_ID INTEGER REFERENCES DEPARTMENT
);

Associations plusieurs à plusieurs

Pour implémenter les associations M: N, une nouvelle relation est créée qui représente l'association. Par exemple, considérons l'association suivante entre l'employé et le projet -

Schema for Works_On Table - WORKS_ON (EMPID, PID, HOURS, START_DATE)

SQL command to create Works_On association - CRÉER UNE TABLE WORKS_ON

( 
   EMPID INTEGER,
   PID INTEGER, 
   HOURS INTEGER,
   START_DATE DATE,
   PRIMARY KEY (EMPID, PID),
   FOREIGN KEY (EMPID) REFERENCES EMPLOYEE,
   FOREIGN KEY (PID) REFERENCES PROJECT 
);

Mappage de l'héritage sur les tables

Pour mapper l'héritage, la clé primaire de la ou des tables de base est affectée comme clé primaire ainsi que la clé étrangère dans la ou les tables dérivées.

Example