Académique Documents
Professionnel Documents
Culture Documents
Projet GPC-2010
André Gamache Département IFT-GLO, Université Laval
Solutions
Usinage et assemblage d’unités de logement pour le compte de promoteurs immobiliers
1 Dirige >
1..* SiteChantier
ClientPromo Finance > * Chef
* 0..1 1
noSC* : int nasC* :int
Associe matCP* : int
villeSC : varchar anServC : int
noAs* :int nomCP : varchar Supervise > lesTel : varray
nomAs adrCP : varchar 1..* 0..3 0..1
capAs : <<Projet>> ChangerChef()
(interface)
noP* : int
Proprio >
CompteBanque
livraisonP :Date
Usine
totalBudgetP : real noCB* : int
noU* : int margeP : real soldeCB : real
villeU : varchar dateOuvCB : Date
… dateFinCB : Date
PayerPar>
1 ….
(c,d) 1
1..*
Coordonne * ProjetCourant ProjetTermine
Réponses
Etape 1 : Transformez le diagramme de classe UML en un modèle navigationnel qui tient compte le plus
possible des contraintes notamment le sens du parcours des associations du diagramme de classe.
Gardez le nom des attributs et des associations.
Avec les étapes suivantes, vous implantez le modèle graduellement, par sous-modèles tel que présenté dans
l’étape en incluant les règles de gestion et les contraintes (contrainte d’attribut, de table et des triggers s’il y
a lieu) qui sont pertinentes. Lors de l’intégration, des contraintes supplémentaires devront être ajoutées.
© A. Gamache BDOO, Département d’informatique et de génie logiciel, faculté des Sciences et de génie, Université Laval,
Québec, Qc, Canada, G1K 7P4. Courriel : andre.gamache@ift.ulavala.ca
2
Etape 1 :
ClientPromo
matCP* : int
nomCP : varchar
adrCP : varchar
lesChantiers
lesAssocies Chef
SiteChantier nasC*:int
Associe anServC : int
noSC* : int
lesTel : varray
villeSC : varchar
noAs
leChefDirige
nomAs
leChefSuper
capAs
<<Projet>> ChangerChef()
(interface)
noP* : int
livraisonP :Date
Usine totalBudgetP : real CompteBanque
Proprio
margeP : real noCB* : int
noU* : int leClient soldeCB : real
villeU : varchar leProjet dateOuvCB : Date
dateFinCB : Date
(c,d)
ProjetCourant ProjetTermine
ChargeProjet
stDepensePC : real totalDepensesPT : real
Les opérations des classes du diagramme DC-UML ne sont pas incluses. L’implantation de ce modèle est
faite par étapes successives dont l’aboutissement fournira le schéma total.
Etape 2
Supervision et direction de chantier (une partie du diagramme de classe)
Chaque chantier est dirigé par un chef mandaté par le ou les clients-promoteurs qui fiancent le chantier.
L’avancement des travaux des chantiers est aussi supervisé par un chef senior mandaté par les clients-
promoteurs impliqués dans le financement d’un chantier. Ce superviseur, choisi parmi les chefs de
chantier voit à informer les différents clients promoteurs sur l’avancement des travaux des chantiers qu’ils
financent. Un chef senior peut superviser jusqu’à 3 chantiers en cours. S’il dirige un chantier, il le
supervise obligatoirement. Les deux autres chantiers ne sont pas nécessairement sous sa direction.
© A. Gamache BDOO 2
3
ChangerChef()
Chef
nas* :int
SiteChantier
anServ : int
noSC* : int
villeSC : varchar
leChefDirige
leChefSuper
ChangerChef()
Questions :
2.1 Formulez et implantez (sans les interfaces) le schéma objet correspondant à ce modèle. Créez les
tables nécessaires.
2.2 Prenez en compte les contraintes pertinentes à ce modèle dans le DDL seulement. N’implémentez
pas à ce stade les contraintes formulées pour implémenter les multiplicités des deux associations.
© A. Gamache BDOO 3
4
2.3 Implémentez explicitement la contrainte de non Null pour leChefDirige et celle du Null possible pour
leChefSuper, Ces deux contraintes ciblent le chef et sont ajoutées sans recréer la table.
Un attribut de référence doit être non null et tandis que l’autre peut-être null.
Alter table SiteChantier add Constraint c3_leChefDirige Check( leChefDirige IS NOT NULL) ;
2.4 Les multiplicités 0..1 et 0..3 des associations sont implémentées par des triggers d’objet BEFORE
INSERT lesquels triggers sont associés aux objets de la table-objet SiteChantier.
/* pour la multiplicité 0,1 de Dirige */
Create or Replace trigger tr_leChefDirige BEFORE Insert ON SiteChantier
for each row
Declare
res number := 0;
chefexiste Exception ;
autreErreur Exception ;
Begin
Select Count(*) into res From SiteChantier sc Where sc.leChefDirige = :new.leChefDirige;
If res != 0 then Raise chefexiste ; Else raise autreErreur ;
End If;
End;
Exception
When chefExiste then Raise_Application_Error(-20100, ‘le chef existe déjà’) ;
When autreErreur then Raise_Application_Error (20105, ‘erreur activée non traitée
spécifiquement’) ;
End ;
/
/* pour la multiplicité 0,3 */
Create or replace trigger tr_leChefSuper BEFORE Insert On SiteChantier
for each row
Declare
res number := 0;
Begin
Select count(*) into res From SiteChantier sc Where sc.leChefSuper = :new.leChefSuper;
If res = 3 then Raise_Application_Error ( - 20205, 'déjà 3 superviseurs pour ce site') ;
Else Null ;
End If;
End;
/
© A. Gamache BDOO 4
5
2.5 Ajoutez au moins 5 objets pour illustrer les validations des attributs et le déclenchement des triggers.
ERREUR Ó la ligne 1 :
ORA-20100: lien ayant déjà un chef-dirigeant pour ce Site
ORA-06512: "ANGAMW.TR_LECHEFDIRIGE", ligne 7
ORA-04088: erreur lors d'exécution du déclencheur 'ANGAMW.TR_LECHEFDIRIGE'
2.6 Expliquez brièvement comment il sera possible de rechercher tous les sites-chantiers supervisés par
un chef particulier (le nasC sera fourni) et donnez un exemple de clause SQL pour y arriver. Exécuter la
clause pour obtenir un résultat significatif.
Pour y arriver, il faut utiliser l’oid du chef dont le nasC est connu. Cet oid sera comparé avec l’oid
de la référence leChefDirige de la table SiteChantier.
© A. Gamache BDOO 5
6
2.7 Écrivez un trigger pour valider que parmi les chantiers supervisés par un chef se trouve aussi un
chantier qu’il dirige. Ce trigger du genre Before est fusionné avec le trigger qui vérifie qu’un même chef
supervise jusqu’à un maximum de 3 chantiers.
Etape 3
Agrégation forte
Une partie du diagramme de classe UML de GPC est donné ci-dessous pour représenter les clients
promoteurs immobiliers et leurs associés. 1Un client corporatif peut avoir plusieurs associés investisseurs
qui amènent un capital limité dans le financement des chantiers. Le diagramme UML modélise avec une
agrégation forte ou dite de composition.
0..* ClientPromo :
Associe : matCP* : int
nomCP : varchar
noAs* :int adrCP : varchar
nomAs
capAs : real
modifnomClientPromo()
ajoutClientPromo()
augmenteCapital()
ClientPromo :
matCP* : int
nomCP : varchar
adrCP : varchar
lesAssocies
Associe : associe_t
noAs : int
nomAs :
capAs : int
augmenteCapital()
modifNomClient()
ajoutClientPromo
Le modèle navigationnel comprend un lien interne multiple et son interface composée de signatures.
modifNomClient() : méthode pour modifier le nom d’un client-.
ajoutClientPromo :`méthode pour ajouter un nouveau client–promoteur.
© A. Gamache BDOO 6
7
AugmenteCapital() : méthode pour augmenter de 10% le capital d’un associé. Cette méthode devra être
appelée par un objet-colonne.
Questions :
3.1 Expliquez brièvement la sémantique de l’agrégation forte dans ce petit modèle. Quel impact cette
agrégation sous-tend-elle lors des traitements.
Comme le stipule le scénario, lorsqu’un Client-promoteur cesse ses activités alors le lien avec ses
associes disparaît automatiquement. En implantant la composition avec une classe interne, en
supprimant un objet Client-Promoteur, ses associés sont aussi supprimés sans autres opérations.
3.2 Implémentez ce modèle (sans l’interface) : types et tables ainsi que les contraintes pertinentes à ce
modèle avec le DDL et si nécessaire, avec les triggers.
Create or replace Type associe_t as Object (noAs int, nomAs varchar2(30), capAs int)
/
Create OR Replace Type lesAssocies_t AS TABLE OF associe_t
/
Create Type clientPromo_t as Object (matCP int, nomCP varchar2(30), adrCP varchar2(30),
lesAssocies lesAssocies_t)
/
La contrainte se définit au niveau de la table, et ici au niveau de la table imbriquée, APRES la
création de la table contenante.
Les contraintes sur les attributs de l’objet-colonne ou de la table imbriquée s’appliquent sur la
table physique créée pour stocker les objets de la table imbriquée.
Dans ce cas-ci la table physique est connue car elle a été nommée par la création de la table
principale : TablelesAssocies
3.3 Ajoutez quelques objets pour illustrer les instances possibles pour cette base correspondant au
modèle navigationnel. Une instance possible est définie comme un état valide de la base qui vérifie toutes
les contraintes.
© A. Gamache BDOO 7
8
)));
3.4 Formulez les deux signatures des méthodes, augmenteCapital pour augmenter le capital d’un associé
d’un pourcentage et modifNomClient() pour modifier le nom d’un client-promoteur. Ajoutez les deux
signatures à la classe externe ClientPromo..
Alter type clientPromo_t ADD Member Procedure augmenteCapitalAsso (capital In real) Cascade ;
Declare
cp clientPromo_t ;
Begin
cp := NEW clientPromo_t ( 10034, ‘Jacques’, null, lesAssocies_t(associe_t(null, null, null))) ;
cp.modifNomClientPromo ; -- appel de la méthode
End ;
/
3.7 Écrivez un applicatif (bloc anonyme) en PL\SQL pour lancer l’exécution d’une procédure PL/SQL
appelée MajNomClient incluse dans un package nommé MAJ pour modifier le nom d’un client que vous
avez inscrit au préalable dans la base.
© A. Gamache BDOO 8
9
NB Il faut donc créer le package PL/SQL MAJ comprenant une procédure. Cette dernière sera appelée
(via le package) par un applicatif avec le <nom de la proc>.
La spécification du package :
Create or Replace Package Maj as
Procedure MajNomClient (mat IN int, nouvN IN varchar) ;
End Maj ;
/
Create or Replace package body MAJ as
Procedure MajNomClient (mat IN int, nouvN IN varchar) is
Begin
Update ClientPromo set nomCP = nouvN Where matCP = mat ;
End ;
End ;
/
L’applicatif est donc un bloc PL/SQL pouvant être aussi simple que :
Begin
MAJ.MajNomClient (10034, ‘Marie’) ;
End ;
/
Cependant, pour l’exécuter comme un énoncé SQL il faut faire un Execute :
© A. Gamache BDOO 9
10
Etape 4
Le DC-UML ci-dessous représente les projets qui sont terminés, leur financement ainsi que leur
propriétaire. Une partie du modèle a été faite dans une étape précédente.
Pour les projets en cours, les charges mensuelles sont payées sous certaines conditions par un compte
bancaire associé à chaque projet.
Un projet courant se termine en se transformant (par un applicatif) en projet terminé lequel appartient à un
client promoteur.
1
ClientPromo
*
1
Associe matCP* : int
nomCP : varchar
noAs*
adrCP : varchar
nomAs
capAs augmenteCapitalAsso
modifNomClientPromo
<<Projet>>
noP* : int
CompteBanque
livraisonP :Date
Proprio totalBudgetP : noCB* : int
real soldeCB : real
margeP : real dateOuvCB : Date
ProjetCourant ProjetTermine
stDepensePC : real totalDepensesPT : real
cumulPayePC : real
margeDispPC : real
© A. Gamache BDOO 10
11
ClientPromo
matCP* : int
nomCP : varchar
adrCP : varchar
lesAssocies
associe_t
noAs
nomAs
capAs
<<Projet>> CompteBanque
AugmenteCapital
noP* : int noCB* : int
ModifNomClientPromo
livraisonP :Date soldeCB : real
totalBudgetP : real dateOuvCB : Date
Proprio
margeP : real dateFinCB : Date
refClient
refProjet …
(c,d)
ProjetCourant ProjetTermine
(interface)
Questions :
N.B. Lorsqu’il est demandé de développer une méthode, il faut aussi démontrer qu’elle s’exécute
correctement.
4.1 Donnez le schéma objet et créez les tables de ce modèle, incluant les contraintes pertinentes.
Les types :
Create type Projet_t as Object (noP int, livraisonP Date, totalBudgetP real, margeP real)
NOT INSTANTIABLE NOT FINAL
/
Create type compteBanque_t as Object (
noCB int,
soldeCB real,
© A. Gamache BDOO 11
12
dateOuvCB Date,
dateFinCB Date) FINAL INSTANTIABLE
/
Les tables-objets :
Il y a 4 tables à créer : ProjetCourant, ProjetTermine, CompteBanque et Proprio. Les attributs
hérités n’ont pas à être décrits. Cependant les contraintes de chaque table doivent l’être même si
elles le sont avec des attributs hérités.
© A. Gamache BDOO 12
13
Aucune clé primaire n’est déclarée pour la table Proprio bien que pour chaque objet Proprio soit
distinct lorsqu’il y une valeur combinée de deux oids. En l’absence d’un oid sur ProjetTerminé, les
2 attributs ne peuvent pas jouer le rôle de clé.
4.2 Expliquez comment il faut implémenter la contrainte disjoint de la spécialisation de la classe abstraite
Projet.
La classe abstraite <<Projet>> permet l’héritage des attributs et des signatures. Elle ne peut pas
être instanciée (NOT INSTANTIABLE) mais elle est spécialisée (NOT FINAL). Il ne pourra donc pas
y avoir d’objet du type projet_t.
Pour valider le disjoint, il faut vérifier que tout projet peut-être soit dans une ou l’autre des tables
mais pas dans les deux. La somme des objets dans les deux tables correspond à la somme des
projets.
© A. Gamache BDOO 13
14
4.3 Surchargez le constructeur de clientPromo_t pour créer un nouveau client-promoteur qui n’aura
jamais d’associés.
En surchargeant ce constructeur, tout clientPromo créé avec ce constructeur ne pourra jamais
avoir d’associés. Si cela change par la suite, la mise ne sera pas possible autrement qu’en
recréant cet objet avec son constructeur implicite autorisant les associés.
4.4 Ajoutez une méthode Member Ajout de type procedure dans le type projetCourant_t afin d’ajouter un
projetCourant avec le no, la date de livraison et le budget total fournis par l’appel de la méthode
La clause CASCADE est nécessaire si la classe abstraite a été spécialisée. Avec CASCADE, la
nouvelle procédure devient visible par les sous-classes.
4.5 Modifiez le type pour ajouter le body de la méthode Ajout du type ProjetCournt_t de manière à insérer
un projet courant qui initialise automatiquement les autres attributs. Ces derniers sont null ou zéro sauf la
marge disponible qui est initialisée automatiquement comme 10% du budget total.
© A. Gamache BDOO 14
15
4.6 Formulez une méthode Static supp() dans le type ProjetCourant_t, signature et corps pour supprimer
un projet-courant. Expliquez comment elle est appelée dans une application. Dans quelles opérations
une telle méthode est utilisée.
Avec une méthode STATIC, le self n’est pas disponible et la méthode est appelée par son nom.
L'usage du SELF est donc interdit puisqu'il n'y a pas d'objet appelant. Une telle méthode est utile
pour les suppressions des objets dans les tables objets, sans avoir à créer un objet complet non
persistant pour appeler la méthode STATIC, il suffit d’avoir la clé, soit dans ce cas-ci le no de
projet à supprimer.
Le corps de la méthode :
4.7 Formulez une méthode (fonction) MAP mesureRisq pour comparer deux projets courants sur la base
du risque associé à chacun, mesuré par la différence entre le budget total et la marge consentis par la
banque à chaque projet. Une différence similaire pour 2 projets indique que les deux projets sont aussi
similaires sur la base du risque. Le projet avec le plus grand risque est celui dont la différence est la plus
grande pour le risque associé à deux objets.
© A. Gamache BDOO 15
16
Fonction sans liste de paramètres qui retourne un type simple : Char, varchar2 Real, Number et
Date. La valeur retournée pour chaque objet permet de vérifier une relation d'ordre entre les
objets. Chaque objet correspond à une valeur unique formée à partir des attributs de l'objet et qui
le positionne sur un axe linéaire. Une méthode MAP doit être définie obligatoirement à la racine
d’une hiérarchie.
Alter type projet_t ADD Map Member Function mesureRisq Return real Cascade;
DECLARE -- Applicatif
p1 projetCourant_t ;
p2 projetCourant_t ;
BEGIN
p1 := projetCourant_t (1100, null , 200000, 10000, 0, 0, 10000, null); -- projet plus risqué
p2 := projetCourant_t (1101, null , 100000, 50000, 0, 0, 50000, null);
IF p1 >p2 Then DBMS_OUTPUT.PUT_LINE(' *****p1 PLUS risqué que p2 ******');
ELSE DBMS_OUTPUT.PUT_LINE('****** p1 MOINS risqué que p2 *******');
END IF;
END;
/
****************************************
© A. Gamache BDOO 16
17
4.8 Formulez une méthode ORDER compareProjet() pour tester la similarité relative de deux projets
courants. Deux projets courants sont similaires si la date de livraison de chacun est à un mois près et
leur budget égaux à 10% près.
La méthode ORDER compareProjet() doit être programmée pour retourner un entier comme résultat pour
indiquer la similarité de 2 projetCourants:
-1 l'objet du paramètre est plus petit que celui qui l'appelle;
0 si les 2 objets sont égaux
+1 l'objet du paramètre est plus grand que celui qui l'appelle;
Alter type Projet_t ADD ORDER MEMBER FUNCTION CompareProjet (u Projetc_t) Return integer
cascade;
L’applicatif ci-dessous comparera les deux objets, Pour comparer tous les objets deux à deux, il
faudra faire appel à deux curseurs parcourus pour faire la lecture du produit cartésien.
DECLARE
p1 Projetc_t ;
p2 Projetc_t;
BEGIN
p1 := Projetc_t(1200,'16-10-2009',9898,98989); -- objet non persistant
p2 := Projetc_t(1300,'16-10-2009',9898,98989);
IF p1 = p2 Then DBMS_OUTPUT.PUT_LINE( '*****projet1 et projet2 sont égaux*****');
ELSE DBMS_OUTPUT.PUT_LINE('*******projet1 et projet2 sont différents********');
END IF;
END;
© A. Gamache BDOO 17
18
Etape 5
Le modèle navigationnel du GPC initial est ainsi obtenu par l’intégration des sous-modèles précédents.
Modification du GPC navigationnel pour obtenir un GPC*
Ce modèle GPC initial est enrichi par l’ajout d’attributs et de liens interne et externe :
a- Un nouvel attribut à la classe SiteChantier est ajouté pour représenter deux numéros de téléphone pour
à chaque chantier. Ces téléphones sont utilisés pour rejoindre le chef ou le superviseur. Le premier (1) est
le téléphone cellulaire du chef de chantier et le deuxième (2) est le téléphone cellulaire portable du
superviseur. L’ordre des numéros d’appel est donc significatif. Les deux numéros de téléphone peuvent
être les mêmes dans quelques cas.
b- Dans le modèle obtenu par l’ajout des deux numéros de téléphone, il faut aussi implémenter
l’association Supervise différemment pour privilégier un parcours de l’association Supervise vers
SiteChantier. L e modèle obtenu est le GPC*.
Etape 6
6.1 Développez une application en PL/SQ utilisant que des méthodes pour effectuer l’affichage d’un
compte bancaire pour un client particulier.
***
© A. Gamache BDOO 18