7 de la conception à l'implementationefreidoc.fr/L2 -...

24
1 De la conception à l’implémentation Implémentation des agrégations

Transcript of 7 de la conception à l'implementationefreidoc.fr/L2 -...

  • 1

    De la conception à l’implémentation

    Implémentation des agrégations

  • 2

    Implémentation des agrégations en C++ (1/5)

    Benoît Charroux - De la conception à l’implémentation- Juillet 99 - 3

    class Moteur{private :

    char* type ;public :

    Moteur( const char* ) ;~Moteur() ;Moteur( const Moteur & ) ;Moteur & operator = ( const Moteur & ) ;

    } ;

    #include "moteur.h"class Voiture{private :

    char* marque ;��������������

    ����������

    public :Voiture( const char* marqueVoiture, const char* marqueMoteur ) ;~Voiture() ;Voiture( const Voiture & ) ;Voiture & operator = ( const Voiture & ) ;

    } ;

    • Agrégation en déclarant un objet dans un autre :

    Implémentation de la classe moteur (2/5)

    Benoît Charroux - De la conception à l’implémentation- Juillet 99 - 4

    Moteur::Moteur( const char* nom ){type = new char[ strlen(nom) + 1 ] ;strcpy( type, nom ) ;

    }Moteur::~Moteur(){

    delete [] type ;}Moteur::Moteur( const Moteur & v ){ // constructeur par recopie ...

    type = new char[ strlen(v.type) + 1 ] ; // s’il y a des parties dynamiquesstrcpy( type, v.type ) ;

    }Moteur & Moteur::operator = ( const Moteur & v ){ // opérateur d’affectation

    if( this != &v ){ // s’il y a des partiesdelete [] type ; // dynamiquestype = new char[ strlen(v.type) + 1 ] ;strcpy( type, v.type ) ;

    }return *this ;

    }

  • 3

    Implémentation de la classe voiture (3/5)

    Benoît Charroux - De la conception à l’implémentation- Juillet 99 - 5

    • La copie de l’agrégat entraîne la copie de l’agrégé :

    voiture1 : Voiture

    voiture2 : Voiture

    moteur1 : Moteur

    moteur1 : Moteur

    copie copie

    Voiture::Voiture( const Voiture & v ) �������������������� {// appel du constructeur ...marque = new char[ strlen(v.marque) + 1 ] ; // par recopie de la classe ...strcpy( marque, v.marque ) ; // moteur

    }

    • Appel du constructeur par recopie de la classe Moteur dans le constructeur par recopie de la classe Voiture :

    Implémentation de la classe voiture (4/5)

    Benoît Charroux - De la conception à l’implémentation- Juillet 99 - 6

    voiture1 : Voiture

    voiture2 : Voiture

    moteur1 : Moteur

    moteur1 : Moteur

    • La destruction de l’agrégat entraîne la destruction de l’agrégé :

    Voiture::~Voiture(){delete [] marque ;

    }

    • Appel automatique du destructeur de Moteur :

  • 4

    Implémentation de la classe voiture (fin) (5/5)

    Benoît Charroux - De la conception à l’implémentation- Juillet 99 - 7

    // constructeurVoiture::Voiture( const char* marqueVoiture, const char* marqueMoteur ) :

    ������� ������������ � { // appel du constructeur de la classe Moteurmarque = new char[ strlen(marqueVoiture) + 1 ] ;strcpy( marque, marqueVoiture ) ;

    }

    // surcharge de l’opérateur =Voiture & Voiture::operator = ( const Voiture & v ){

    if( this != &v ){������������������ // appel de l’opérateur = de la classe Moteurdelete [] marque ;marque = new char[ strlen(v.marque) + 1 ] ;strcpy( marque, v.marque ) ;

    }return *this ;

    }

    Implémentation d’une agrégation par un pointeur (1/3)

    Benoît Charroux - De la conception à l’implémentation- Juillet 99 - 8

    #include "moteur.h »class Voiture{private :

    ���������������

    �����������������������char* marque ;

    public :Voiture( const char* marqueVoiture, const char* marqueMoteur ) ;

    �������������������

    ���������

    ~Voiture() ;Voiture( const Voiture & ) ;Voiture & operator = ( const Voiture & ) ;

    } ;

    • L’implémentation d’une agrégation par un pointeur à l’avantage :

    • de bénéficier du polymorphisme ;

    • de permettre l’adoption (l’agrégation ne se fait pas à la construction des objets mais n’importe quand).

  • 5

    Implémentation de la classe Voiture (2/3)

    Benoît Charroux - De la conception à l’implémentation- Juillet 99 - 9

    // constructeurVoiture::Voiture( const char* marqueVoiture, const char* marqueMoteur ) : �������������������������������� {

    marque = new char[ strlen(marqueVoiture) + 1 ] ;strcpy( marque, marqueVoiture ) ;

    }

    // destructeurVoiture::~Voiture(){

    ������ �������delete [] marque ;

    }

    // adoption���������������������������������������������

    Implémentation de la classe voiture (fin) (3/3)

    Benoît Charroux - De la conception à l’implémentation- Juillet 99 - 10

    // constructeur par recopieVoiture::Voiture( const Voiture & v ) : �������������������������������� {

    marque = new char[ strlen(v.marque) + 1 ] ;strcpy( marque, v.marque ) ;

    }

    // opérateur d’affectationVoiture & Voiture::operator = ( const Voiture & v ){

    if( this != &v ){����������������������delete [] marque ;marque = new char[ strlen(v.marque) + 1 ] ;strcpy( marque, v.marque ) ;

    }return *this ;

    }

  • 6

    Implémentation des associations

    en C++

    Modéliser les associations par des attributs

    • Selon la cardinalités des associations des attributs peuvent être placés :

    • dans une des classes pour les associations de 1 vers 1 ;

    • dans la classe côté N pour les associations de 1 vers N ;

    • il est possible de promouvoir une association au rang de classe pour augmenter la lisibilité.

    Benoît Charroux - De la conception à l’implémentation- Juillet 99 - 12

  • 7

    Modéliser les associations par des attributs

    • Pour placer des attributs, il faut déterminer si une association se traduit par un lien unidirectionnel ou bidirectionnel :

    • unidirectionnel : un seul attribut est alors nécessaire ;

    • bidirectionnel : deux attributs ou une classe d’association sont nécessaires.

    Exemple tiré de la gestion d’une médiathèque

    Lien unidirectionnel

    Liens bidirectionnels

    Benoît Charroux - De la conception à l’implémentation- Juillet 99 - 13

    Implémentation d’une association unidirectionnelle en C++ (1/2)

    Benoît Charroux - De la conception à l’implémentation- Juillet 99 - 14

    class Emplacement ;class Exemplaire{

    ����� ������������ ������public :

    Exemplaire() ;// mise a jour de l’associationvoid setEmplacement( Emplacement* emplacement ) ;Emplacement* getEmplacement() ;

    } ;

    class Emplacement{int rayon ;

    public :// ...

    } ;

    void main(){Emplacement emplacement ;Exemplaire exemplaire ;exemplaire.setEmplacement( &emplacement ) ;Emplacement* place = exemplaire.getEmplacement() ;

    }

    • Une association unidirectionnelle s’implémente à l’aide d’un pointeur.

  • 8

    Implémentation d’une association unidirectionnelle en C++ (2/2)

    Benoît Charroux - De la conception à l’implémentation- Juillet 99 - 15

    Exemplaire::Exemplaire(){emplacement = NULL ;

    }void Exemplaire::setEmplacement( Emplacement* emplacement ){

    this->emplacement = emplacement ;}Emplacement* Exemplaire::getEmplacement(){

    return emplacement ;}

    • Implémentation de la classe Exemplaire :

    Association unidirectionnelle de 1 vers plusieurs en C++ (1/3)

    Benoît Charroux - De la conception à l’implémentation- Juillet 99 - 16

    void main(){Entreprise monEntreprise( "Mon entreprise" ) ;

    Client client1( 1 ) ; // création d’un clientmonEntreprise.addClient( client1 ) ; // ajoute un client à l’entreprise

    Client client2( 2 ) ; // création d’un deuxième clientmonEntreprise.addClient( client2 ) ; // ajoute un deuxième client

    monEntreprise.removeClient( client1 ) ; // supprime le premier client}

    • Une association unidirectionnelle s’implémente à l’aide d’un tableau de pointeurs, d’un vecteur, ...

  • 9

    Association unidirectionnelle de 1 vers plusieurs en C++ (2/3)

    Benoît Charroux - De la conception à l’implémentation- Juillet 99 - 17

    // vecteurs de clients�!����"��� ���#$�����%�$&'�()*�

    class Entreprise{string nom ;// association entreprise / clients$&'�()*� �����+�

    public :Entreprise( const string & ) ;string getNom() ;// mise a jour de l’associationvoid addClient( Client & ) ;void removeClient( const Client & ) ;const CLIENTS & getClients() ;

    } ;

    class Client{int numero ;

    public :Client( int numero ) ;int getNumero() ;int operator == ( const Client & ) ;int operator != ( const Client & ) ;

    } ;

    • Utilisation des vecteurs de la Standard Template Library.

    Association unidirectionnelle de 1 vers plusieurs en C++ (3/3)

    Benoît Charroux - De la conception à l’implémentation- Juillet 99 - 18

    void Entreprise::addClient( Client & client ){int i = 0 ; // cherche si le client est déjà présentwhile( i

  • 10

    Association bidirectionnelle de 1 vers 1 en C++ (1/3)

    Benoît Charroux - De la conception à l’implémentation- Juillet 99 - 19

    void main(){Homme h ;Femme f ;h.setFemme( &f ) ;

    }

    class Homme ;class Femme{

    public :Homme* homme ;Homme* GetHomme() ;void setHomme( Homme* ) ;

    } ;

    class Femme ;class Homme{

    public :Femme* femme ;Femme* GetFemme() ;void setFemme( Femme* ) ;

    } ;

    • Les attributs de l’association sont publics => on peut les manipuler directement et individuellement, or la mise à jour doit être faite simultanément des deux cotés de l’association.

    • Une association bidirectionnelle s’implémente à l’aide d’un pointeurs dans chaque classe :

    Association bidirectionnelle de 1 vers 1 en C++ (2/3)

    Benoît Charroux - De la conception à l’implémentation- Juillet 99 - 20

    Homme* Femme::GetHomme(){

    return homme ;}void Femme::setHomme( Homme* homme ){

    this->homme = homme ;homme->femme = this ;

    }

    Femme* Homme::GetFemme(){

    return femme ;}void Homme::setFemme( Femme* femme ){

    this->femme = femme ;femme->homme = this ;

    }

  • 11

    Solution partielle pour éviter les attributs publics:fonctions amies(3/3)

    Benoît Charroux - De la conception à l’implémentation- Juillet 99 - 21

    #include "femme.h"class Homme{

    private :Femme* femme ;"���������� ,������+��-������-��������

    public :Femme* GetFemme() ;void setFemme( Femme* ) ;

    } ;class Homme ;class Femme{

    public :Homme* homme ;Homme* GetHomme() ;void setHomme( Homme* ) ;

    } ;

    Fonction ayant accès à l’attribut femme.

    Attribut privé

    Association bidirectionnelle de 1 vers plusieurs en C++ (1/6)

    Benoît Charroux - De la conception à l’implémentation- Juillet 99 - 22

    typedef vector EXEMPLAIRES ;class Oeuvre{

    // ...�.��/&0'1�*��2��������+��

    public :// ...

    } ;

    void main(){Oeuvre donGiovani( "Don Govani" ) ;Exemplaire exp1( 10 ) ;donGiovani.addExemplaire( exp1 ) ;

    }

    • Parcours de l’association dans le sens Œuvre -> Exemplaire :

    class Exemplaire{// ...

    public :3������ ������ // ...

    } ;

  • 12

    Association bidirectionnelle de 1 vers plusieurs en C++ (2/6)

    Benoît Charroux - De la conception à l’implémentation- Juillet 99 - 23

    • Déclaration de la classe Oeuvre :

    typedef vector EXEMPLAIRES ;class Oeuvre{

    string titre ;EXEMPLAIRES exemplaires ; // association œuvre / exemplaires

    public :Oeuvre( const string & titre ) ;string getTitre() ;// fonctions ayant acces a l'association exemplairesfriend void Exemplaire::addOeuvre( Oeuvre & ) ;friend void Exemplaire::removeOeuvre( Oeuvre & ) ; // mise a jour de l'associationvoid addExemplaire( Exemplaire & ) ;void removeExemplaire( const Exemplaire & ) ;const EXEMPLAIRES & getExemplaires() ;void affiche() ;

    } ;

    Association bidirectionnelle de 1 vers plusieurs en C++ (3/6)

    Benoît Charroux - De la conception à l’implémentation- Juillet 99 - 24

    void Oeuvre::addExemplaire( Exemplaire & exemplaire ){int i = 0 ; // cherche si l’exemplaire est deja presentwhile( i

  • 13

    Association bidirectionnelle de 1 vers plusieurs en C++ (4/6)

    Benoît Charroux - De la conception à l’implémentation- Juillet 99 - 25

    void main(){Oeuvre donGiovani( "Don Govani" ) ;Exemplaire exp1( 10 ) ;exp1.addOeuvre( donGiovani ) ;

    }

    • Parcours de l’association dans le sens Exemplaire -> Œuvre :

    Association bidirectionnelle de 1 vers plusieurs en C++ (5/6)

    Benoît Charroux - De la conception à l’implémentation- Juillet 99 - 26

    class Oeuvre ;class Exemplaire{

    int numero ;public :

    3������ ������ �

    ��++� �������7�������2��������+Exemplaire( int numero ) ;// mise a jour de l’associationvoid addOeuvre( Oeuvre & ) ;void removeOeuvre( Oeuvre & ) ;

    int operator == ( const Exemplaire & ) ;int operator != ( const Exemplaire & ) ;

    } ;

    • Déclaration de la classe Exemplaire :

  • 14

    Association bidirectionnelle de 1 vers plusieurs en C++ (6/6)

    Benoît Charroux - De la conception à l’implémentation- Juillet 99 - 27

    void Exemplaire::addOeuvre( Oeuvre & oeuvre ){int i = 0 ; // cherche si l’exemplaire est deja presentwhile( ioeuvre = &oeuvre ; // mise a jour du lien avec l’exemplaire

    }else throw "cette exemplaire est deja reference" ;}void Exemplaire::removeOeuvre( Oeuvre & oeuvre ){

    int i = 0 ;EXEMPLAIRES::iterator theIterator ; // parcours des exemplairestheIterator = oeuvre.exemplaires.begin(); // se positionne sur le premierwhile( ioeuvre = NULL ;

    }else throw "exemplaire inconnu" ;}

    Association bidirectionnelle de 1 vers plusieurs en C++ (1/6)

    Benoît Charroux - De la conception à l’implémentation- Juillet 99 - 28

    • Modélisation d’une association bidirectionnelle par une classe d’association ;

    • utilisation d’une table de hachage de la STL (map) : un ensemble d’œuvres (vecteur) est accessible par un nom d’auteur (clef).

    typedef vector OEUVRES ;typedef map DICO_AUTEUR_OEUVRES ;class Oeuvre{

    // ...8'$390:)�:193�:�1�*��� ��

    public :// ...

    } ;

    class Oeuvre ;class Auteur{

    // ...public :

    // ...// fonction pour comparer deux clefs de type auteur (voir oeuvre.h)bool operator()( const Auteur & s1, const Auteur & s2 ) const ;

    } ;

  • 15

    Association bidirectionnelle de 1 vers plusieurs en C++ (2/6)

    Benoît Charroux - De la conception à l’implémentation- Juillet 99 - 29

    • Déclaration de la classe Œuvre :

    typedef vector OEUVRES ;typedef map DICO_AUTEUR_OEUVRES ;class Oeuvre{

    string titre ;DICO_AUTEUR_OEUVRES dico ;friend void Auteur::addOeuvre( Oeuvre & oeuvre ) ;friend void Auteur::removeOeuvre( Oeuvre & oeuvre ) ;

    public :Oeuvre( const string & titre ) ;string getTitre() ;// mise a jour de l’association auteur/oeuvresvoid addAuteur( Auteur & ) ; // ajout d’un auteur au dicovoid removeAuteur( Auteur & ) ; // suppression d’un auteur du dicoDICO_AUTEUR_OEUVRES & getDico() ;// pour comparer deux oeuvres (voir Auteur::addOeuvre() )bool operator == ( const Oeuvre & ) ;bool operator != ( const Oeuvre & ) ;

    } ;

    Association bidirectionnelle de 1 vers plusieurs en C++ (3/6)

    Benoît Charroux - De la conception à l’implémentation- Juillet 99 - 30

    • Implémentation de la classe Œuvre :

    void Oeuvre::addAuteur( Auteur & auteur ){DICO_AUTEUR_OEUVRES::iterator iter ;iter = dico.find( auteur ) ; // cherche si auteur est une clefif( iter == dico.end() ){ // si l’auteur n’est pas une clef

    OEUVRES oeuvres ; // cree un vecteur d’oeuvresoeuvres.push_back( *this ) ; // ajoute l’oeuvre courantepairp ;p = dico.insert(DICO_AUTEUR_OEUVRES::value_type(auteur,oeuvres));

    }else{ // si auteur est deja une clef OEUVRES::iterator theIterator ; int i = 0 ;theIterator = (*iter).second.begin(); // l’oeuvre courante est-elle liee a cet auteurwhile( i

  • 16

    Association bidirectionnelle de 1 vers plusieurs en C++ (4/6)

    Benoît Charroux - De la conception à l’implémentation- Juillet 99 - 31

    • Implémentation de la classe Œuvre :

    void Oeuvre::removeAuteur( Auteur & auteur ){if ( dico.erase( auteur ) != 1) throw "effacement impossible" ;

    }

    • Déclaration de la classe Auteur :

    class Oeuvre ;class Auteur{

    string nom ;public :

    Auteur( const string & = "" ) ;// mise a jour de l’association auteur/oeuvresvoid addOeuvre( Oeuvre & ) ; // ajoute une oeuvre a l’auteurvoid removeOeuvre( Oeuvre & ) ; // supprime une oeuvre a l’auteur// fonction pour comparer deux clefs de type auteur (voir oeuvre.h)bool operator()( const Auteur & s1, const Auteur & s2 ) const ;

    } ;

    Association bidirectionnelle de 1 vers plusieurs en C++ (5/6)

    Benoît Charroux - De la conception à l’implémentation- Juillet 99 - 32

    • Implémentation de la classe Auteur :

    void Auteur::addOeuvre( Oeuvre & oeuvre ){DICO_AUTEUR_OEUVRES::iterator iter ;iter = oeuvre.dico.find( *this ) ; // cherche si l’auteur courant est une clefif( iter == oeuvre.dico.end() ){ // si l’auteur n’est pas une clef

    OEUVRES oeuvres ; // cree un vecteur d’oeuvresoeuvres.push_back( oeuvre ) ; // y ajoute l’oeuvrepairp ;p = oeuvre.dico.insert(DICO_AUTEUR_OEUVRES::value_type(*this,oeuvres));if( p.second == false ) throw "insertion impossible" ;

    }else{ // si l’auteur est une clefOEUVRES::iterator theIterator ; int i = 0 ; // cherche si l’oeuvre est deja presentetheIterator = (*iter).second.begin();while( i

  • 17

    Association bidirectionnelle de 1 vers plusieurs en C++ (6/6)

    Benoît Charroux - De la conception à l’implémentation- Juillet 99 - 33

    • Implémentation de la classe Auteur :

    void Auteur::removeOeuvre( Oeuvre & oeuvre ) {DICO_AUTEUR_OEUVRES::iterator iter ;iter = oeuvre.dico.find( *this ) ; // cherche si l’auteur courant est une clefif( iter == oeuvre.dico.end() ) // si l’auteur n’est pas une clef

    throw "L’auteur courant n’est pas dans le dictionnaire" ;else{ // si l’auteur est une clef

    OEUVRES::iterator theIterator ;int i = 0 ;theIterator = (*iter).second.begin(); // se positionne sur la premiere oeuvrewhile( i

  • 18

    Implémentation d’une association unidirectionnelle en java

    Benoît Charroux - De la conception à l’implémentation- Juillet 99 - 35

    • Une association unidirectionnelle s’implémente à l’aide d’une référence :

    class Exemplaire{������� ����� ����������� ������

    public void setEmplacement( Emplacement emplacement ){this.emplacement = emplacement ;

    }public Emplacement getEmplacement(){

    return emplacement ;}public static void main( String [] argv ){

    Emplacement emplacement = new Emplacement() ;Exemplaire exemplaire = new Exemplaire() ; // création d’un exemplaireexemplaire.setEmplacement( emplacement ) ; // ajout de l’exemplaireEmplacement place = exemplaire.getEmplacement() ; // récupération de l’emplacement

    }}

    class Emplacement{private int rayon ;// ...

    }

    Association unidirectionnelle de 1 vers plusieurs en java (1/3)

    Benoît Charroux - De la conception à l’implémentation- Juillet 99 - 36

    public static void main( String [] argv ){Entreprise monEntreprise = new Entreprise( "Mon entreprise" ) ;Client client1 = new Client( 10 ) ; // création d’un clienttry{

    monEntreprise.addClient( client1 ) ; // ajout du clientClient client2 = new Client( 20 ) ; // création d’un clientmonEntreprise.addClient( client2 ) ; // ajout du clienttry{

    monEntreprise.removeClient( client2 ) ; // suppression d’un client} catch( ClientNonReferenceException e ) {

    System.out.println( e ) ;}

    } catch ( ClientDejaReferenceException e ) {System.out.println( e ) ;

    }

    • Une association unidirectionnelle s’implémente à l’aide d’un vecteur, ...

  • 19

    Association unidirectionnelle de 1 vers plusieurs en java (2/3)

    Benoît Charroux - De la conception à l’implémentation- Juillet 99 - 37

    • Implémentation de la classe Entreprise :

    import java.util.Vector ;class Entreprise{

    private String nom ;���������� ��� �����+������ �� ������

    ��++� ���������������+��� �����+public Entreprise( String nom ){

    this.nom = nom ;}public void addClient( Client client ) throws ClientDejaReferenceException{

    if( clients.contains( client ) == false ) // si le client est déjà référencé ...clients.addElement( client ) ; // on l’ajoute

    elsethrow new ClientDejaReferenceException( "Client deja present" ) ;

    }public void removeClient( Client client ) throws ClientNonReferenceException{

    if( clients.removeElement( client ) == false ) // si le client est inconnuthrow new ClientNonReferenceException( "Client inconnu de l'entreprise" ) ;

    }}

    Association unidirectionnelle de 1 vers plusieurs en java (3/3)

    Benoît Charroux - De la conception à l’implémentation- Juillet 99 - 38

    • Implémentation de la classe Client :

    class Client{private int numero ;public Client( int numero ){

    this.numero = numero ;}public int getNumero(){

    return numero ;}

    // fonction utilisée par contains de Vector pour savoir si un client // est déjà présent : 2 clients sont égaux s’ils ont même numéro

    public boolean equals( Object obj ){if( (obj!=null) && (obj instanceof Client) )

    return numero == ((Client)obj).numero ;else return false ;

    }}

  • 20

    Association bidirectionnelle de 1 vers 1 en java

    Benoît Charroux - De la conception à l’implémentation- Juillet 99 - 39

    class Homme{Femme femme ;public Femme GetFemme(){

    return femme ;}public void setFemme( Femme femme ){

    this.femme = femme ;femme.homme = this ;

    }}

    class Femme{Homme homme ;public Homme GetHomme(){

    return homme ;}public void setHomme( Homme homme ){

    this.homme = homme ;homme.femme = this ;

    }public static void main( String [] argv ){

    Homme h = new Homme() ;Femme f = new Femme() ;h.setFemme( f ) ;

    }}

    • Les attributs de l’association peuvent être manipulés directement dans le même package, on peut les mettre à jour individuellement sans respecter la mise à jour simultanée des deux cotés de l’association.

    Association bidirectionnelle de 1 vers plusieurs en java (1/4)

    Benoît Charroux - De la conception à l’implémentation- Juillet 99 - 40

    import java.util.Vector ;class Oeuvre{

    �� ��� �2��������+������� �� ������// ...

    }

    public static void main( String [] argv ){Oeuvre donGiovani = new Oeuvre( "Don Govani" ) ;Exemplaire exp1 = new Exemplaire( 10 ) ;donGiovani.addExemplaire( exp1 ) ;

    }

    • Parcours de l’association dans le sens Œuvre -> Exemplaire :

    class Exemplaire{3������������ // …

    }

  • 21

    Association bidirectionnelle de 1 vers plusieurs en java (2/4)

    Benoît Charroux - De la conception à l’implémentation- Juillet 99 - 41

    • Implémentation de la classe Oeuvre

    class Oeuvre{private String titre ;Vector exemplaires = new Vector() ; // association oeuvre / exemplairespublic void addExemplaire( Exemplaire exemplaire )throws ExemplaireDejaReferenceException{

    if( exemplaires.contains( exemplaire ) == false ){// si l'exemplaire est déjà référencé ...exemplaires.addElement( exemplaire ) ; // on l’ajouteexemplaire.oeuvre = this ; // mise a jour du lien avec l’exemplaire

    }else throw new ExemplaireDejaReferenceException( "Exemplaire deja present" ) ;

    }public void removeExemplaire( Exemplaire exemplaire ) throws ExemplaireNonReferenceException{

    if( exemplaires.removeElement( exemplaire ) == false )// si l'exemplaire est inconnuthrow new ExemplaireNonReferenceException( "Exemplaire inconnu" ) ;

    else exemplaire.oeuvre = null ; // mise a jour du lien avec l'exemplaire }

    }

    Association bidirectionnelle de 1 vers plusieurs en java (3/4)

    Benoît Charroux - De la conception à l’implémentation- Juillet 99 - 42

    public static void main( String [] argv ){Oeuvre donGiovani = new Oeuvre( "Don Govani" ) ;Exemplaire exp1 = new Exemplaire( 10 ) ;exp1.addOeuvre( donGiovani ) ;

    }

    • Parcours de l’association dans le sens Exemplaire -> Œuvre :

  • 22

    Association bidirectionnelle de 1 vers plusieurs en java (4/4)

    Benoît Charroux - De la conception à l’implémentation- Juillet 99 - 43

    • Implémentation de la classe Exemplaire :

    class Exemplaire{private int numero ;Oeuvre oeuvre ;public void addOeuvre( Oeuvre oeuvre ) throws ExemplaireDejaReferenceException{

    if( oeuvre.exemplaires.contains( this ) == false ){// si l'exemplaire est déjà référencé ...oeuvre.exemplaires.addElement( this ) ; // on l’ajoutethis.oeuvre = oeuvre ; // mise a jour du lien exemplaire

    }else throw new ExemplaireDejaReferenceException( "Exemplaire deja present" ) ;

    }public void removeOeuvre( Oeuvre oeuvre )throws ExemplaireNonReferenceException{

    if( oeuvre.exemplaires.removeElement( this ) == true ) this.oeuvre = null ; else throw new ExemplaireNonReferenceException( "Exemplaire inconnu" ) ;

    }public boolean equals( Object obj ){

    if( (obj!=null) && (obj instanceof Exemplaire) )return numero == ((Exemplaire)obj).numero ;else return false ;

    }}

    Association bidirectionnelle de 1 vers plusieurs en java (1/4)

    Benoît Charroux - De la conception à l’implémentation- Juillet 99 - 44

    • Modélisation d’une association bidirectionnelle par une classe d’association ;

    • utilisation d’une table de hachage (hashtable) :

    • un ensemble d’œuvres (vecteur) est accessible par un nom d’auteur (clef).

    class Auteur{+���� �-�+4��;�� �� ������� -�+4��;�����

    ������;������ ��++�// ...

    }

  • 23

    Association bidirectionnelle de 1 vers plusieurs en java (2/4)

    Benoît Charroux - De la conception à l’implémentation- Juillet 99 - 45

    class Auteur{private String nom ;static Hashtable dico = new Hashtable() ;public void addOeuvre( Oeuvre oeuvre ) throws OeuvreDejaPresentExecption{

    Vector oeuvres ;oeuvres = (Vector)dico.remove( this ) ; // efface les œuvres pour pouvoir les modifierif( oeuvres == null ) // s’il n’y a pas d’œuvres ...

    oeuvres = new Vector() ; // creation d’un vecteur d’oeuvresif( oeuvres.contains(oeuvre) == false ){ // si œuvre n’est pas presente ...

    oeuvres.addElement( oeuvre ) ; // ajout de oeuvredico.put( this, oeuvres ) ; // mise a jour du dico

    } else { // si œuvre est deja presente ...dico.put( this, oeuvres ) ; // on recre le dico a l’identiquethrow new OeuvreDejaPresentExecption( "Oeuvre deja presente" );

    }}// ...

    }

    • Implémentation de la classe Auteur :

    Association bidirectionnelle de 1 vers plusieurs en java (3/4)

    Benoît Charroux - De la conception à l’implémentation- Juillet 99 - 46

    class Auteur{// ...public void removeOeuvre( Oeuvre oeuvre ) throws OeuvreNonPresentExecption{

    Vector oeuvres ;oeuvres = (Vector)dico.remove( this ) ; // on tente de recuperer les oeuvresif( oeuvres != null ){ // si les oeuvres existent

    if( oeuvres.removeElement(oeuvre) == false ) // on tente d’effacer l’oeuvrethrow new OeuvreNonPresentExecption( "Oeuvre non presente" );

    dico.put( this, oeuvres ) ; // on remet a jour le dictionnaire}else throw new OeuvreNonPresentExecption( "Oeuvre non presente" );

    }}

    • Implémentation de la classe Auteur :

  • 24

    Association bidirectionnelle de 1 vers plusieurs en java (4/4)

    Benoît Charroux - De la conception à l’implémentation- Juillet 99 - 47

    class Oeuvre{private String titre ;public Oeuvre( String titre ){

    this.titre = titre ;}public void addAuteur( Auteur auteur ) throws AuteurDejaPresentExecption{

    Vector oeuvres ;if( auteur.dico.containsKey(auteur) == false ){ // si l’auteur n’est pas present

    oeuvres = new Vector() ; // on cre un vecteur d’oeuvresoeuvres.addElement( this ) ; // on y ajoute l’auteur courantauteur.dico.put( auteur, oeuvres ) ; // ajout dans le dico

    } else {throw new AuteurDejaPresentExecption( "Auteur deja present" ) ;

    }}public void removeAuteur( Auteur auteur ) throws AuteurNonPresentExecption{

    if( auteur.dico.remove(auteur)==null )throw new AuteurNonPresentExecption( "Auteur deja present" ) ;

    }

    • Implémentation de la classe Oeuvre :