Invocació explícita versus invocació implícita: anàlisi comparativa de dos enfocaments de disseny de sistemes d'informació
Abstract
The main goal of this work is to develop an initial characterization of an information systems design approach that we call implicit invocation and to analyse its potential advantatges and disadvantatges with respect to the conventional approach that we call explicit invocation. Our work tries to contribute to this approach at the specific field of object oriented design of information systems. In our analysis we use an example that consist in some simplified banking operations, that we use as basis for the comparation of the alternative designs we explore. We characterize what could be implicit invocation in information systems design, we apply this characterization to the example, and we present a comparative analysis of the two designs.
Full text
Invocació explícita versus invocació implícita: Anàlisi comparativa de dos enfocaments de disseny de Sistemes d’Informació. Cristina Gómez1 Luis Felipe Fernández1 (∗) Juan Ramón López2 Antoni Olivé1 (1) LSI - Facultat d’Informàtica - Universitat Politécnica de Catalunya C/Jordi Girona Salgado, 1-3, Edif. C6. 08034 Barcelona - Catalunya. { luisf, cristina, olive }@lsi.upc.es (2) Dpto. Computación - Facultade de Informática - Universidade da Coruña Campus de Elviña s/n 15071 A Coruña - Galicia [email protected] ∗ Becario de la Universidad Autónoma de Ciudad Juárez (UACJ) con fondos PROMEP. (lfer[email protected])
Resum L’objectiu principal d’aquest treball és desenvolupar una caracterització inicial d’un enfocament de disseny de sistemes d’informació, que anomenarem d’invocació implícita, i analitzar els seus avantatges i inconvenients potencials en relació a l’enfocament convencional, que anomenem d’invocació explícita. El nostre treball pretén contribuir a aquest enfocament a l’àmbit específic del disseny orientat a objectes de sistemes d’informació. Al nostre anàlisi usem un exemple consistent en algunes operacions, simplificades, del sector bancari. Concretament, és una extensió de l’estàndard conegut al món de las bases de dades com Debit-Credit [Ano85], que utilitzem com a base de comparació pel disseny alternatiu que explorem. Es caracteritza el que podria ser la invocació implícita en el disseny de sistemes d’informació, apliquem aquesta caracterització a l’exemple, i es presenta una anàlisi comparativa dels dos dissenys.
Índex 1. Introducció. ................................ ................................ ................................ ................................ ..... 1 2. Presentació de l’exemple. ................................ ................................ ................................ ............... 2 3. Disseny del sistema: Invocació explícita. ................................ ................................ ...................... 2 4. Caracterització de la invocació implícita en sistemes d’informació. ................................ ......... 7 4.1 Esdeveniments ................................ ................................ ................................ ............................. 8 4.2 Anunci d’esdeveniments ................................ ................................ ................................ ............. 9 4.3 Subscripcions ................................ ................................ ................................ ............................. 10 4.4 Gestor d’esdeveniments ................................ ................................ ................................ ............. 12 5. Disseny del sistema: Invocació implícita. ................................ ................................ ................... 13 5.1 Esdeveniments externs de consulta. ................................ ................................ .......................... 15 5.2 Esdeveniments externs d’actualització ................................ ................................ ...................... 16 5.3 Esdeveniments externs de petició d’acció ................................ ................................ ................. 19 6. Anàlisi comparativa dels dos dissenys. ................................ ................................ ....................... 22 6.1 Introducció ................................ ................................ ................................ ................................ . 22 6.2 Anàlisi quantitativa ................................ ................................ ................................ .................... 23 6.2.1 WMC. ................................ ................................ ................................ ................................ .. 23 6.2.2 DIT. ................................ ................................ ................................ ................................ ..... 23 6.2.3 NOC ................................ ................................ ................................ ................................ .... 24 6.2.4 CBO ................................ ................................ ................................ ................................ ..... 24 6.2.5 RFC ................................ ................................ ................................ ................................ ..... 24 6.2.6 LCOM. ................................ ................................ ................................ ................................ 24 6.3 Anàlisi qualitativa. ................................ ................................ ................................ ..................... 31 6.3.1 Afegir un nou atribut, el valor del qual s’obté amb els esdeveniments ja existents ........... 31 6.3.2 Afegir un nou esdeveniment que afecta a classes o atributs ja existents. ........................... 33 7. Conclusions. ................................ ................................ ................................ ................................ ... 35 8. Referències. ................................ ................................ ................................ ................................ .... 36
1 1. Introducció. L’objectiu principal d’aquest report és el de desenvolupar una caracterització inicial d’un enfocament de disseny de sistemes d’informació, que anomenem d’invocació implícita, i analitzar-ne els seus avantatges i inconvenients potencials en relació a l’enfocament convencional, que anomenem d’invocació explícita. L’enfocament d’invocació implícita no és nou en el disseny de sistemes software. Des de fa temps, de quan en quan apareixen treballs, usant –com acostuma a passarnoms diversos, que l’usen en algun sistema concret o que l’avaluen. D’entre aquests treballs mencionem [Sul92], que l’anomena invocació implícita/mitjancer, i que l’usa per al disseny i construcció d’entorns integrats d’eines software; [Sha96] que l’anomena invocació implícita, integració reactiva o difusió selectiva, i fa una proposta detallada de com es podria incorporar en els llenguatges de programació d’ús general; i [Lar98] que l’anomena disseny basat en notificació d’esdeveniments, i en descriu algunes de les seves qualitats distintives. La invocació implícita també està present en alguns patrons de disseny populars, com ara l’Observador [Gam95], el Model-Vista-Controlador o l’Agent [Bus96], i el de Notificació d’esdeveniments [Rie96]. La idea de la invocació implícita s’utilitza també, a vegades, fora de l’àmbit del disseny de sistemes. Es pot considerar semblant a les regles causa-efecte de ROSES [Cos97], que és un llenguatge per a la modelització conceptual de sistemes d’informació. També es pot fer correspondre a les regles de les bases de dades actives [Wid96], on l’ocurrència d’un esdeveniment invoca, implícitament, accions definides en regles. El nostre treball preten contribuir a aquest enfocament en l’àmbit específic del disseny orientat a objectes de sistemes d’informació. Pretenem caracteritzar la invocació implícita en aquest àmbit concret, i analitzar-ne els avantatges i inconvenients en relació al disseny convencional dels sistemes d’informació. L’objectiu de fons del nostre treball és millorar el disseny de sistemes d’informació. En principi, aquesta millora podria intentar-se en diverses propietats d’un disseny, però nosaltres volem centrar-nos en la millora de la propietat no-funcional anomenada “canviabilitat”, que inclou els aspectes de mantenibilitat, extensibilitat, reestructuració i portabilitat [Bus96]. Considerem que aquesta propietat és crítica per a la majoria dels sistemes d’informació i que encara calen més esforços per a millorar-la. En aquest sentit, volem explorar fins a quin punt un ús enraonat de la invocació implícita podria augmentar la canviabilitat del software. Aquest report s’estructura en sis seccions, que giren al voltant d’un exemple concret. En la secció 2 fem una breu descripció d’aquest exemple. En la secció 3 presentem un disseny convencional, usant la invocació explícita, del sistema. Usarem aquest disseny com a base de comparació per al disseny alternatiu que explorem. A la secció 4 tractem de caracteritzar el que podria ser la invocació implícita en el disseny de sistemes d’informació. A la secció 5 apliquem aquesta caracterització a l’exemple. En la secció 6 fem una anàlisi comparativa dels dos dissenys obtinguts. Les conclusions del nostre treball, i les línies de recerca futures, les exposem en la secció 7.
2 2. Presentació de l’exemple. L’exemple que usarem per a la nostra anàlisi consisteix en algunes operacions, simplificades, del sector bancari. Concretament, és una extensió de l’estàndard conegut en el món de les bases de dades com a Debit-Credit [Ano85]. En aquesta secció en farem una breu presentació general. Els detalls els anirem explicant en la secció següent, conjuntament amb el primer disseny que fem del sistema. Suposem un banc que disposa d’un conjunt d’oficines repartides per un cert territori. Els clients del banc tenen comptes oberts en les oficines. Hi ha dues menes de comptes: d’estalvi i corrent. La diferència principal entre un i altre està en el càlcul dels interessos, i en les operacions que s’hi poden fer, però en aquest exemple no aprofundirem gaire en les diferències. Un compte corrent pot estar vinculat a un compte d’estalvi. Cada oficina té un conjunt de caixers automàtics, en els quals poden operar els clients amb els seus comptes (ingressos i reintegraments). Els clients poden fer operacions en les dues menes de comptes. Si es fa un reintegrament d’un compte corrent, i no hi ha prou saldo i el compte està associat a un compte d’estalvi amb saldo suficient, es fa un traspàs automàtic d’un compte a l’altre, per l’import necessari. Els reintegraments es poden fer sempre que en el caixer on es demanen hi hagi diners suficients. Tenen un efecte immediat sobre el saldo dels comptes corresponents. Els ingressos, en canvi, s’accepten provisionalment, fins que són confirmats per un operador. Un cop confirmats, s’incrementa el saldo amb la quantitat ingressada. Tots els moviments dels comptes s’han de guardar en un arxiu històric. Tots els comptes estan assignats a una oficina. Per cada oficina es manté un atribut saldo, que té un valor igual a la suma dels saldos dels comptes que té assignats. 3. Disseny del sistema: Invocació explícita. Com és ben conegut, es poden fer diversos dissenys diferents d’un mateix sistema amb un mateix estil de disseny, i per a un mateix entorn d’execució. Nosaltres estem interessats en l’estil orientat a objectes i, per als nostres propòsits, aquí en tenim prou amb suposar un entorn d’execució centralitzat, ignorant els aspectes de concurrència i persistència. Per fer el disseny, usarem el mètode descrit a [Mar95], tant perquè és prou representatiu dels mètodes existents, com perquè es basa en la consideració dels esdeveniments externs (també anomenats transaccions) com a objectes (normalment transitoris), aspecte aquest que creiem molt rellevant en els sistemes d’informació. Mètodes que es poden considerar semblants a aquest són els descrits a [Coa95, Lar98]. Com a notació, usarem el llenguatge UML. La Figura 3.1 mostra el diagrama de classes del sistema. No s’inclouen els tipus dels atributs ni els paràmetres de les operacions. La classe Compte és abstracta, i defineix els atributs i les operacions comuns a les dues subclasses. L’operació saldo?():Integer es pot usar per conèixer el saldo d’un compte. L’operació ingressar(i:Integer) s’usarà per comunicar al sistema que s’ha produït un ingrés al compte corresponent, per un import i. L’operació reintegrar(i:Integer) també es defineix en Compte.
3 import quan confirmat Compte saldo saldo? ingressar reintegrar disponible disponible? afegir treure Caixer Oficina saldo saldo? moviment Història tipus import quan IngrésPdt * * * * * * 1 1 1 1 1 0..1 0..1 associatA CompteCorrent estalvi ? CompteEstalvi Figura 3.1: Diagrama de classes d'objectes Com hem indicat, en aquest disseny els esdeveniments externs es consideren com a objectes, de les classes corresponents. Definim una classe abstracta esdeveniment extern (EsdevExt), que només té definida una operació virtual executar(), amb tres subclasses, també abstractes, per diferenciar els esdeveniments externs que són de consulta (EsdExtCons), d’actualització (EsdExtAct) i de petició d’acció (EsdExtPetAcc). L’operació executar() s’ha de definir en cada esdeveniment extern: el seu mètode ha de realitzar les accions corresponents. En la Figura 3.2 mostrem alguns d’aquests esdeveniments externs. EsdevExtern executar () EsdExtCons EsdExtAct SaldoCompte OmplirCaixer Compte executar () executar () import Caixer 1 1 Confirmar IngrésEnCaixer Ingrés import import IngrésPdt executar () executar () executar () 1 1 1 Compte 1 EsdExtPetAcc Figura 3.2: Diagrama de classes d'esdeveniments
4 L’esdeveniment extern SaldoCompte té només un paràmetre, que és el compte que es vol consultar. El diagrama de seqüència de la Figura 3.3 mostra l’efecte de la seva execució: és simplement invocar l’operació saldo?() del compte. : SaldoCompte : Compte executar saldo? Figura 3.3: Diagrama seqüència SaldoCompte L’esdeveniment extern OmplirCaixer té dos paràmetres: el caixer al qual s’afegeix diners i la quantitat que s’afegeix. La seva execució invoca l’operació afegir(i:Integer), que tindrà l’efecte de sumar la quantitat i a l’atribut disponible del caixer. La Figura 3.4 en mostra el diagrama de seqüència. : OmplirCaixer : Caixer executar afegir Figura 3.4: Diagrama seqüència OmplirCaixer Malgrat que aquests dos esdeveniments externs són molt simples, ja es pot veure l’essència del disseny amb invocació explícita: l’operació executar ha de conèixer les operacions existents dels altres objectes, i invocar explícitament aquelles que produiran l’efecte desitjat. En el cas de SaldoCompte, l’efecte d’executar() ha de ser retornar el saldo del compte, i això ho pot fer saldo?(). En el cas de OmplirCaixer, l’efecte d’executar() ha de ser que el caixer incrementi el valor de disponible. Qui ho pot fer és l’operació afegir(i:Import), per tant s’ha d’invocar explícitament aquesta operació per tal que ho faci. L’esdeveniment extern IngrésEnCaixer (que es produeix quan un client introdueix diners en un caixer, per ser ingressats en un cert compte) té tres paràmetres: El compte al qual es vol ingressar, el caixer on es fa l’ingrés, i l’import. L’ingrés no té un efecte immediat sobre el compte, sinó que requereix una confirmació posterior. Per aquest motiu, l’únic que cal fer es guardar l’ingrés en un objecte de la classe IngrésPdt. La Figura 3.5 mostra el diagrama de seqüència.
5 : IngrésEnCaixer : IngrésPdt executar Figura 3.5: Diagrama seqüència IngrésEnCaixer Per confirmar un ingrés, un operador del banc usa l’esdeveniment extern Confirmar. La Figura 3.6 en mostra el diagrama de seqüència. L’execució de l’esdeveniment extern invoca l’operació confirmat, la qual ha de garantir que el saldo del compte corresponent s’incrementi, així com el de l’oficina a la qual està assignat i, alhora, que s’enregistri l’ingrés en la història de moviments. L’operació ingressar(i:Integer) de compte proporciona tota aquesta funcionalitat. Li cal invocar l’operació moviment(i:Integer) d’oficina i crear un nou objecte de la classe Història. :Confirmar : Compte executar : IngrésPdt ingressar confirmat :Oficina : Història moviment Figura 3.6: Diagrama seqüència Confirmar També es poden fer ingressos en comptes directament (transferències, etc.). Per aquest propòsit s’usa l’esdeveniment extern Ingrés, amb l’efecte documentat a la Figura 3.7. L’execució d’aquest esdeveniment ha d’implicar que el saldo del compte corresponent s’incrementi, així com el de l’oficina a la qual està assignat i, alhora, que s’enregistri l’ingrés en la història de moviments. Com hem vist abans (Figura 3.6) l’operació ingressar(i:Integer) de compte proporciona tota aquesta funcionalitat. : Ingrés : Compte executar ingressar Figura 3.7: Diagrama seqüència Ingrés Queda per definir els dos esdeveniments externs de reintegrament. La Figura 3.8 descriu la seva estructura.
6 EsdExtReint import Caixer ReEstalvi executar () 1 CompteEstalvi ReCorrent executar () CompteCorrent 1 1 0..1 EsdevExtern executar () EsdExtPetAct Figura 3.8: Diagrama de classes d'esdeveniments externs L’esdeveniment extern ReEstalvi extreu diners d’un compte d’estalvi, sempre i quan hi hagi saldo suficient. L’esdeveniment es pot fer, o no, des d’un caixer. En el primer cas, cal que el caixer tingui prou diners disponibles. La Figura 3.9 ens mostra el diagrama de seqüència, per l’escenari de reintegrament des d’un caixer on hi ha diners al caixer i saldo suficient. Observi’s que s’invoca l’operació reintegrar(i:Import), definida a nivell compte. : ReEstalvi : Caixer executar : CompteEstalvi disponible? saldo? reintegrar :Oficina : Història moviment treure Figura 3.9: Diagrama seqüència ReEstalvi L’esdeveniment extern ReCorrent és una mica més complex, perquè si no hi ha saldo suficient en el compte corrent, però hi ha un compte d’estalvi associat, amb el saldo mínim necessari, es pot fer un traspàs d’aquest a aquell. La Figura 3.10 mostra el diagrama de seqüència d’aquest esdeveniment extern per l’escenari:
13 Gestor d’esdeveniments Objecte Objecte Anunci esdeveniment Subscripció when esdeveniment e if condició tell to objecte . operació Invocació operació Figura 4.6: Esquema general des del punt de vista del GE 5. Disseny del sistema: Invocació implícita. En aquest punt mostrarem el disseny amb invocació implícita de l’exemple descrit al punt 3. Utilitzarem en aquest disseny el GE i les tres premisses fonamentals definides al punt 4. Veurem així que és possible construir un disseny on no hi ha invocacions explícites entre objectes. Per fer aquest nou disseny definim un nou diagrama de classes semblant a l’anterior però amb algunes diferències. La Figura 5.1 mostra el diagrama de classes del sistema: import quan confirmat compte ? Import ? caixer ? Compte Saldo saldo? ingressar reintegrar oficina? disponible disponible? afegir treure Caixer Oficina saldo saldo? moviment Història tipus import quan IngrésPdt * * * * * * 1 1 1 1 1 0..1 CompteEstalvi 0..1 associatA CompteCorrent estalvi ? GE anunciSíncron anunciAsíncron subscripció Figura 5.1: Diagrama de classes d'objectes Com es pot veure en aquesta figura, les diferències fonamentals amb el diagrama de classes de
14 la Figura 3.1 són les noves operacions de consulta que s’han d’afegir a alguns objectes per ser utilitzades a la clàusula where d’algunes subscripcions. S’afegeix també una classe per al GE amb operacions de anunci i subscripció. A les Figura 5.2, Figura 5.3 i Figura 5.4 es mostra el diagrama de classes d’esdeveniments. EsdevExtern executar () EsdExtCons EsdExtAct SaldoCompte OmplirCaixer Compte executar () executar () import Caixer 1 1 Confirmar IngrésEnCaixer Ingrés import import IngrésPdt executar () executar () executar () 1 1 1 Compte 1 EsdExtPetAcc EsdevGenerat Esdeveniment Figura 5.2: Diagrama de classes d'esdeveniments EsdExtReint import Caixer ReEstalvi executar () 1 CompteEstalvi ReCorrent executar () CompteCorrent 1 1 0..1 EsdevExtern executar () EsdExtPetAct Esdeveniment Figura 5.3: Diagrama de classes d'esdeveniments externs
15 ESaldoCompte1 compte : Compte Caixer 0..1 EsdevGenerat Esdeveniment EOmplirCaixer1 caixer : Caixer import : Integer EIngrésEnCaixer1 caixer : Caixer import : Integer compte : Compte quan : Time EConfirmar1 ingresPdt : IngresPdt EConfirmar2 caixer : Caixer import : Integer compte : Compte EIngrés1 compte : Compte import : Integer EIngrés2 import : Integer compte : Compte oficina:Oficina EReCorrent1 caixer : Caixer EReCorrent2 compte : Compte EReCorrent3 compte : Compte EReCorrent4 caixer : Caixer import : Integer compte : Compte EReEstalvi1 caixer : Caixer EReEstalvi2 compte : Compte EReEstalvi4 caixer : Caixer import : Integer compte : Compte oficina:Oficina EReEstalvi3 caixer : Caixer import : Integer compte : Compte EsdevGenConsulta EsdevGenActualització Figura 5.4: Diagrama de classes d'esdeveniments generats Com es pot veure a la figura anterior, afegim al diagrama de classes d’esdeveniments una nova classe abstracta que anomenarem esdeveniment generat. Aquesta classe tindrà dos subclasses també abstractes per representar els esdeveniments generats de consulta i actualització. Com a subclasses d’aquestes classes tindrem tots els esdeveniments que el nou disseny exigeix generar. Pel moment, proposem la següent notació pels esdeveniments generats: E<nom_esd_extern_que_el_genera><num_seqüència> A continuació mostrarem els diagrames de seqüència de tots els esdeveniments externs. Per claredat, agruparem els diagrames de seqüència segons el tipus d’esdeveniment extern (consulta, actualització i petició d’acció). 5.1 Esdeveniments externs de consulta. Cada vegada que es produeix un esdeveniment extern de consulta, aquest donarà lloc a un esdeveniment generat de consulta i a un anunci al GE. Cada esdeveniment generat de consulta ha de tenir associat com a mínim una subscripció que impliqui una operació de consulta. En el nostre disseny tenim un cas d’esdeveniment extern de consulta: SaldoCompte. El
16 diagrama de seqüència per aquest cas es mostra a continuació. :SaldoCompte e:ESaldoCompte1 :GE executar anunciSíncron(e) when ESaldoCompte1 e tellTo e.compte.saldo?( ) :Compte saldo? Figura 5.5: Diagrama de seqüència SaldoCompte L’esdeveniment extern SaldoCompte dóna lloc a un esdeveniment generat ESaldoCompte1 (d’acord amb la notació proposada), que tindrà com argument el compte. Aquest esdeveniment s’anuncia al GE mitjançant l’operació anunciSíncron. El GE invoca l’operació saldo sobre l’objecte compte. El GE coneix la subscripció que es mostra a la Figura 5.5. 5.2 Esdeveniments externs d’actualització Cada vegada que es produeix un esdeveniment extern d’actualització, aquest donarà lloc a un esdeveniment generat d’actualització i a un anunci al GE. Cada esdeveniment generat d’actualització ha de tenir associat com a mínim una subscripció i aquesta pot implicar més d’una operació d’actualització. En el nostre disseny tenim quatre esdeveniments externs d’actualització: OmplirCaixer, IngrésEnCaixer, Confirmar, Ingrés. El diagrama de seqüència per OmplirCaixer es mostra a continuació. :OmplirCaixer e:EOmplirCaixer1 :GE executar anunciAsíncron(e) when EOmplirCaixer1 e tellTo e.caixer.afegir (e.import) :Caixer afegir Figura 5.6: Diagrama de seqüència OmplirCaixer
17 En aquest cas es produeix un esdeveniment generat EOmplirCaixer1 que té com a argument el caixer. Aquest esdeveniment s’anuncia al GE. El gestor invoca l’operació afegir sobre l’objecte Caixer. Cal remarcar que aquest esdeveniment extern no requereix resposta. Al igual que en el cas anterior el GE té una subscripció que es mostra a la Figura 5.6. En el següent diagrama (IngrésEnCaixer) seguim el mateix procediment: :IngrésEnCaixer e:EIngrésEnCaixer1 :GE executar anunciAsíncron(e) :IngrésPdt when EIngrésEnCaixer1 e tellTo IngrésPdt.IngrésPdt(e.caixer,e.compte,e.import,e.quan) Figura 5.7: Diagrama de seqüència IngrésEnCaixer El següent diagrama correspon a l’esdeveniment extern Confirmar: :Confirmar e1:EConfirmar1 :GE executar anunciAsíncron(e1) when EConfirmar1 e1 itellTo e.ingresPdt.confirmat( ) :IngresPdt confirmat e2:EConfirmar2 anunciAsíncron(e2) :Compte ingressar e3:EIngres2 anunciAsíncron(e3) :Oficina moviment :Història when EConfirmar2 e2 tellTo e.compte.ingressar (e.import, e.caixer) Figura 5.8: Diagrama de seqüència Confirmar (primera versió) En aquest cas hem utilitzat el mateix procediment de disseny que als anteriors. Cal destacar que en aquest diagrama es produeix una situació nova: la invocació d’una operació per part del GE, IngresPdt::confirmat, dóna lloc a un esdeveniment generat d’actualització, EConfirmar2, ja que hi ha una certa dependència entre l’operació invocada i les operacions
18 associades al nou esdeveniment que es genera. El mateix succeeix amb l’operació Compte::ingressar i l’esdeveniment EIngrés2. Aquest esdeveniment no segueix la nomeclatura que hem proposat, ja que sempre que utilitzem l’operació ingressar es genera el mateix esdeveniment amb el mateix nom EIngrés2 A la Figura 5.8 també podem veure, per primera vegada, una subscripció (l’associada a EIngrés2) on apareix la invocació de vàries operacions pel mateix esdeveniment. Per una altra banda, en el cas de poder suposar una independència entre les operacions a invocar llavors tindríem la possibilitat d’associar totes les operacions a un mateix (i únic) esdeveniment generat d’actualització. Això ens donaria un disseny alternatiu tal i com es mostra a la Figura 5.9. :Confirmar e1:EConfirmar1 :GE executar anunciAsíncron(e1) when EConfirmar1 e1 tellTo e.ingresPdt.confirmat( ) tellTo co.ingressar (import) tellTo co.oficina?( ).moviment (import) tellTo Història.Història ("I",import,ara,co,e.ingresPdt.caixer?( )) where co=e.ingresPdt.compte?( ) import=e.ingresPdt.import?( ) :IngresPdt :Compte ingressar :Oficina moviment :Història confirmat Figura 5.9: Diagrama seqüència Confirmar (segona versió) A la subscripció de l’anterior figura, com a l’esdeveniment generat d’actualització no tenim tota la informació necessària per invocar les operacions, fem servir la clàusula where. En concret, a l’esdeveniment EConfirmar1 només tenim la informació d’IngrésPdt i l’import. Per conèixer el compte i l’oficina associades, fem ús de les operacions de consulta (IngrésPdt::compte?, Compte::oficina?). Existeix un últim esdeveniment extern d’actualització: Ingrés. Donat que es semblant als anteriors només mostrarem els diagrames corresponents a les dues alternatives de disseny possibles.
19 :Ingrés e1:EIngrés1 :GE executar anunciAsíncron(e1) when EIngrés1 e1 tellTo e.compte.ingressar (e.import, ) :Compte ingressar e2:EIngrés2 anunciAsíncron(e2) moviment :Oficina :Història when EIngrés2 e2 tellTo e.oficina.moviment (e.import) tellTo Història.Història("I",e.import,ara,e.compte, ) Figura 5.10: Diagrama seqüència Ingrés (primera versió) :Ingres e1:EIngrés1 :GE executar anunciAsíncron(e1) when EIngrés1 e1 if (no cond) tellTo e.compte.ingressar (e.import) tellTo e.compte.oficina?( ).moviment (e.import) tellTo Història.Història ("I",e.import,ara,e.compte, ) :Compte ingressar :Oficina moviment :Història Figura 5.11: Diagrama seqüència Ingrés (segona versió) 5.3 Esdeveniments externs de petició d’acció Cada vegada que es produeix un esdeveniment extern de petició d’acció, aquest donarà lloc a un o més esdeveniments generats de consulta i a un o més esdeveniments generats d’actualització. En el nostre exemple tenim dos esdeveniments externs de petició d’acció: ReEstalvi i ReCorrent. A la Figura 5.12 es mostra el diagrama de seqüència de ReEstalvi.
20 :ReEstalvi executar e1:EReEstalvi1 :GE :Caixer :CompteEstalvi :Oficina e2:EReEstalvi2 e3:EReEstalvi3 :Història anunciSíncron(e2) anunciSíncron(e1) anunciAsíncron(e3) disponible? saldo? reintegrar moviment treure when EReEstalvi1 e tellTo e.caixer.disponible?() when EReEstalvi2 e tellTo e.compte.saldo?() when EReEstalvi3 e tellTo e.compte.reintegrar(e.import) tellTo e.caixer.treure(e.import) tellTo of.moviment(e.import) tellTo Història.Història("I",e.import,ara,e.compte,e.caixer) where of = e.compte.oficina?() Figura 5.12: Diagrama seqüència ReEstalvi (cas d’independència) :ReEstalvi executar e1:EReEstalvi1 :GE :Caixer :CompteEstalvi :Oficina e2:EReEstalvi2 e3:EReEstalvi3 e4:EReEstalvi4 :Història anunciSíncron(e2) anunciSíncron(e1) anunciAsíncron(e3) disponible? saldo? reintegrar moviment treure anunciAsíncron(e4) when EReEstalvi1 e1 tellTo e.caixer.disponible?() when EReEstalvi2 e2 tellTo e.compte.saldo?() when EReEstalvi3 e3 tellTo e.compte.reintegrar(e.import, e.caixer) tellTo e.caixer.treure(e.import) when EReEstalvi4 e4 tellTo e.oficina.moviment(e.import) tellTo Història.Història("I",e.import,ara,e.compte,e.caixer) Figura 5.13: Diagrama seqüència ReEstalvi (cas de dependència)
21 El processament d’aquest esdeveniment extern exigeix l’avaluació d’una sèrie de condicions, a partir del resultat d’una sèrie de consultes. Per això es produeixen una sèrie d’esdeveniments generats de consulta. Una vegada que s’han avaluat les condicions s’hauran d’efectuar les actualitzacions corresponents. En aquest cas suposarem que totes les operacions a invocar són independents i per tant les associarem totes a un mateix esdeveniment generat d’actualització: EReintegramentEstalvi3. Pel cas de depèndencia entre les operacions, la Figura 5.13 mostra el diagrama de seqüència de l’esdeveniment extern ReEstalvi. La Figura 5.14 mostra el diagrama de seqüència de l’esdeveniment extern ReCorrent. :ReCorrent e1:EReCorrent1 :GE anunciSíncron(e1) :Caixer disponible? e2:EReCorrent2 anunciSíncron(e2) saldo? :CompteCorrent e3:EReCorrent3 anunciSíncron(e3) saldo? :CompteEstalvi e4:EReCorrent4 anunciAsíncron(e4) :Oficina :ReintEstalvi executar :Ingres executar reintegrar moviment :Història treure when EReCorrent1 e1 tellTo e.caixer.disponible?( ) when EReCorrent2 e2 tellTo e.compte.saldo?( ) when EReCorrent3 e3 tellTo e.compte.saldo?( ) when EReCorrent4 e4 tellTo e.compte.reintegrar (e.import, e.caixer) tellTo e.caixer.treure (e.import) tellTo e.compte.oficina?().moviment (e.import) tellTo Història.Història ("R", e.import, ara, e.compte, e.caixer) executar Figura 5.14: Diagrama seqüència ReCorrent (cas d’independència) Aquest diagrama és el resultat d’aplicar el mecanisme utilitzat al cas anterior a l’esdeveniment extern ReCorrent. Part del processament d’aquest esdeveniment extern inclou el processament
22 associat als esdeveniments externs Ingrés i ReEstalvi. Per reutilitzar el codi d’aquests dos esdeveniments permetrem que ReCorrent faci la creació dels dos esdeveniments externs Ingrés i ReEstalvi, i invoqui a les seves operacions d’executar. Aquesta serà l’única excepció que permetrem d’invocacions no fetes des del GE. Com hem pogut observar en els exemples anteriors en cap cas hem fet una reutilització dels esdeveniments generats, per poder associar després conducta específica a cada un d’ells, en el cas de canvis posteriors al disseny. 6. Anàlisi comparativa dels dos dissenys. 6.1 Introducció Com ja hem mencionat, l’objectiu principal d’aquest treball és la comparació de dues aproximacions de disseny de sistemes d’informació. A més a més volem orientar aquesta comparació a la propietat no-funcional de canviabilitat dels dissenys obtinguts mitjançant cada aproximació. No resulta fàcil determinar quina és la tècnica més adequada que ens permet l’obtenció de conclusions realment fiables. És per tant interessant l’estudi de les solucions adoptades en altres treballs davant de situacions semblants. Aquí mencionem [Olivé1], [Olivé2], [Sullivan1], [Sullivan2]. En [Olivé1] i [Olivé2] es fa la comparació de dues aproximacions del modelat conceptual de sistemes d’informació (operacional i deductiu), des de diferents punts de vista: entre ells la propietat de canviabilitat dels models obtinguts amb cada aproximació. Les dues aproximacions (caracteritzades amb un mateix marc de treball) s’apliquen a un SI d’exemple i s’analitza la repercussió, en els models obtinguts, d’una sèrie d’exemples de canvis típics en els requeriments d’un SI. La diferència en els dos treballs radica, fonamentalment, en la complexitat de l’exemple considerat i en la selecció dels tipus de canvis a realitzar. [Sullivan1] presenta una nova aproximació al disseny d’entorns integrats d’eines software. Per demostrar que els dissenys obtinguts a partir d’aquesta aproximació suporten millor els canvis que els produïts per aproximacions més convencionals (entre elles una basada en la invocació explícita) es presenta un exemple simple d’un entorn a dissenyar. Com en el cas anterior, s’observa l’impacte, sobre els dissenys generats per l’exemple, d’un parell de canvis representatius. Aquesta aproximació es torna a avaluar a [Sullivan2], partint de l’experiència de la seva aplicació al disseny d’un entorn integrat real. Pel que fa referència a la propietat de canviabilitat aquesta es justifica amb un exemple real de com es va fer l’adaptació de l’entorn de forma senzilla a un canvi imprevist en la seva funcionalitat. Es pren en consideració també l’opinió de diversos experts sobre les dificultats d’evolució de sistemes desenvolupats a partir de diferents tipus d’aproximacions. Tots aquests són exemples de comparacions basades en un anàlisi qualitatiu. Si tractem d’enfocar la comparació a aspectes quantitatius, un treball interessant és [ChSKeC94], on es presenten un conjunt de mètriques aplicables a dissenys orientats a objectes. Part d’aquestes mètriques permeten quantificar aspectes relacionats amb la canviabilitat del disseny.
29 Response for a Class (RFC) Classes Mètrica I E Oficina 2 2 Caixer 3 3 Compte 4 3 CompteEstalvi 4 3 CompteCorrent 5 4 IngrésPdt 4 1 Història 0 0 Esdeveniment 0 Esd. Generat 0 Consulta 0 ESaldoCompte1 0 EReEstalvi1 0 EReEstalvi2 0 EReEstalvi3 0 EReCorrent1 0 EReCorrent2 0 EReCorrent3 0 EReCorrent4 0 Actualizació 0 EOmplirCaixer1 0 EIngrésEnCaixer1 0 EConfirmar1 0 EConfirmar2 0 EConfirmar3 0 EIngrés1 0 EIngrés2 0 Esd. Extern 1 1 Consulta 1 1 SaldoCompte 3 2 Actualizació 1 1 Ingrés 3 2 OmplirCaixer 3 2 IngrésEnCaixer 3 2 Confirmar 3 2 PeticióAcció 1 1 ReEstalvi 6 5 ReCorrent 11 10 Taula 6.5: Resultats de la mètrica RFC
30 Lack of Cohesion in Methods (LCOM) Classes Mètrica I E Oficina 00 Caixer 00 Compte 00 CompteEstalvi 0 0 CompteCorrent 0 0 IngrésPdt 00 Història 00 Esdeveniment 0 0 Esd. Generat 0 Consulta 0 ESaldoCompte1 0 EReEstalvi1 0 EReEstalvi2 0 EReEstalvi3 0 EReCorrent1 0 EReCorrent2 0 EReCorrent3 0 EReCorrent4 0 Actualizació 0 EOmplirCaixer1 0 EIngrésEnCaixer1 0 EConfirmar1 0 EConfirmar2 0 EConfirmar3 0 EIngrés1 0 EIngrés2 0 Esd. Extern 0 0 Consulta 0 0 SaldoCompte 0 0 Actualizació 0 0 Ingrés 0 0 OmplirCaixer 0 0 IngrésEnCaixer 0 0 Confirmar 0 0 PeticióAcció 0 0 ReEstalvi 0 0 ReCorrent 0 0 Taula 6.6: Resultats de la mètrica LCOM
31 6.3 Anàlisi qualitativa. L’objectiu d’aquest punt és realitzar una comparació qualitativa dels dissenys presentats en aquest treball, per poder avaluar fins a quin punt un ús enraonat de la invocació implícita podria augmentar la canviabilitat del software. Per fer aquesta comparació considerarem dos tipus de canvis habituals que es produeixen en els sistemes d’informació. Aquests canvis consistiran en: • Afegir un nou atribut, el valor del qual s’obté amb els esdeveniments ja existents. • Afegir un nou esdeveniment que afecta a classes o atributs ja existents. 6.3.1 Afegir un nou atribut, el valor del qual s’obté amb els esdeveniments ja existents Anem a examinar quines són les modificacions que calen en els dos enfocaments, si ens afegeixen un nou requeriment: “Volem saber el número d’ingressos que fan els comptes de cada oficina.” Afegir aquest requeriment en el disseny amb invocació explícita suposa els següents canvis: • Afegir a la classe Oficina un atribut Oficina::numIngressos. • Afegir a la classe Oficina una operació Oficina::incrementarNumIngr. • Modificar la operació Compte::ingressar per que invoqui a Oficina::incrementarNumIngr Es mostra a continuació el diagrama de seqüència on hi apareix la nova operació Compte::ingressar. :Ingres executar :Compte ingressar :Oficina moviment :Historia incrementarNumIngr Figura 6.1: Diagrama seqüència Ingrés (invocació explícita) Anem a veure ara com afecta aquesta modificació pel cas de la invocació implícita. Els canvis seran els següents: • Afegir a la classe oficina un atribut Oficina::numIngressos. • Afegir a la classe oficina una operació Oficina::incrementarNumIngr. • A la subscripció on tenim l’esdeveniment que genera l’operació Compte::ingressar cal afegir una nova invocació a l’operació Oficina::incrementarNumIngr.
32 Es mostra a continuació el diagrama de seqüència on hi apareix la modificació. :Ingres :GE executar anunciAsíncron(e2) when EIngres2 e2 tellTo e.oficina.moviment (e.import) tellTo e.oficina.incrementarNumIngr() tellTo Historia.Historia ("I",e.import,ara,e.compte, ) :Compte :Oficina moviment :Historia incrementarNumIngr e1:EIngres1 anunciAsíncron(e1) e2:EIngres2 ingressar when EIngres1 e1 tellTo e.compte.ingressar (e.import, ) Figura 6.2: Diagrama seqüència Ingrés (invocació implícita) Com hem vist en els dos dissenys cal afegir el nou atribut i la nova operació de modificació. En canvi en el disseny amb invocació explícita cal modificar el codi de l’operació Compte::ingressar afegint una crida a l’operació Oficina::incrementarNumIngr, mentre que a l’altre disseny cal afegir una invocació en una subscripció. Tot i que sembla que els canvis en els dos dissenys són semblants hi ha diferències. En el primer cas s’ha de fer la modificació del codi d’una operació. En el segon cas s’ha d’afegir una invocació en una subscripció. Es important destacar que requereix més esforç modificar el codi d’una operació que inserir una nova invocació en una subscripció. En aquest cas afegir un nou requeriment només implica la modificació d’una operació, però es pot donar el cas d’afegir nous requeriments que impliquin canvis en el codi d’operacions més complicats, per exemple que es facin en funció d’unes determinades condicions. Amb la invocació explícita s’han d’inserir aquests canvis en el codi de les operacions mentre que amb la invocació implícita afegirem la invocació i si cal afegirem o modificarem la condició de la subscripció. Tal i com hem afegit aquest nou requeriment al nostre exemple podem observar que hi ha una dependència entre l’operació Compte::ingressar i les operacions Oficina::incrementarNumIngr, Oficina::moviment i el constructor d’Història. Potser en aquest cas seria més real considerar que aquestes operacions no tenen aquesta dependència i que és possible que no totes les transaccions que fan la invocació a l’operació Compte::ingressar volen incrementar el número d’ingressos de la seva oficina. En aquest cas parlem de que hi ha una independència de les operacions. També en aquest cas la modificació que estem considerant tindria el mateix efecte que el cas anterior. En el primer disseny hauríem de cridar a aquesta nova operació des de totes les transaccions que vulguin registrar els ingressos que es fan. En el segon hauríem d’afegir les noves invocacions en les subscripcions. També en aquest cas es requereix més esforç per modificar el codi de totes les transaccions que vulguin registrar el nou requeriment que inserir una nova invocació en les
33 subscripcions que es vegin afectades. 6.3.2 Afegir un nou esdeveniment que afecta a classes o atributs ja existents. En aquest punt, anem a examinar quines són les modificacions que calen en els dos enfocaments si ens afegeixen un nou requeriment: “Volem afegir un nou esdeveniment extern RegalBanc. Aquest esdeveniment tindrà com a paràmetre un compte. El banc farà un ingrés de 500 ptes al compte si aquest té un saldo més gran que 100.000 ptes.” Afegir aquest nou requeriment en el disseny amb invocació explícita suposa els següents canvis: • Construir aquest nou esdeveniment extern. A continuació es mostra el diagrama de seqüència on hi apareix aquesta nova transacció. :RegalBanc executar :Compte ingressar :Oficina moviment :Historia incrementarNumIngr saldo? Figura 6.3: Diagrama seqüència RegalBanc (invocació explícita) Anem a veure com afecta aquest canvi en el cas de la invocació implícita. Els canvis seran els següents: • Construir part del nou esdeveniment. Es mostra a continuació el diagrama de seqüència on apareix la modificació.
34 :RegalBanc :GE executar anunciAsíncron(e2) when ERegalBanc1 e1 tellTo e.compte.saldo?() :Compte ingressar :Oficina moviment :Historia incrementarNumIngr e1:ERegalBanc1 anunciSíncron(e1) saldo? e2:ERegalBanc2 e3:EIngres2 anunciAsíncron(e3) when ERegalBanc2 e2 tellTo e.compte.ingressar (e.import, ) Figura 6.4: Diagrama seqüència RegalBanc (invocació implícita) Com hem vist en els dos dissenys cal afegir un nou esdeveniment. En el cas del disseny amb invocació explícita cal construir tota la transacció des del començament. En canvi en el cas del disseny amb invocació implícita podem observar que es poden afegir les subscripcions associades als esdeveniments que ha de generar el nou esdeveniment. Per tant el codi del nostre esdeveniment extern s’encarregarà de generar els esdeveniments i anunciar-los al GE. El gestor ja té les subscripcions i per tant ja sap a quines operacions s’han d’invocar.
35 7. Conclusions. La contribució d’aquest treball es centra en tres aspectes: • La proposta d’un GE i tres premisses fonaments com a base de disseny de SI amb invocació implícita. • Un segon aspecte és l’aplicació de la visió anterior a un exemple concret. • Per últim, els avantatges que proporciona un disseny basat en aquest enfocament analitzades des d’un punt de vista quantitatiu i qualitatiu. El treball futur té dues vessants: profunditzar en l’estudi del disseny de SI amb invocació implícita i en la implementació del GE. Això inclou: • Definició d’una nova nomenclatura, més adient, pels esdeveniments generats. • Possibilitat de la reutilització d’esdeveniments • Gestió de concurrència. • Aspectes de gestió d’esdeveniments (anunci, invocació i subscripció) • Tractament d’excepcions produïdes per operacions invocades pel GE. • Coexistència de la invocació implícita i explícita en un mateix disseny. Delimitació dels casos en que resulta més adient una o l’altra.
36 8. Referències. [Ano85] Anon et al. “A measure of Transaction Processing Power”, Datamation, April. [Bub86] Bubenko, J.A.; Olivé, A. “Dynamic or Temporal modeling? - an illustrative comparison” SYSLAB Working Paper Nr. 117, 21 November [Bus96] Buschmann,F.; Meunier,R.; Rohnert,H.; Sommerlad,P. Stal,M. “Pattern-Oriented Software Architecture. A System of Patterns”, John Wiley. [Coa95] Coad, P.; North, D.; Mayfield, M. “Object Models. Strategies, Patterns and Applications”, Yourdon Press. [Cos97] Costal, D. Et al. “The Cause-Effect Rules of ROSES”, Proc. ADBIS’97, St. Petersburg, pp. 399-405. [Chi94] Chidamber, S.R., Kemerer, C.F. “A metrics suite for object oriented design”, IEEE Transactions on Software Engineering, Vol. 20, No. 6, June, pp. 476-493 [Gam95] Gamma,E.; Helm,R.; Johnson,R.; Vlisides,J. “Design Patterns”. Elements of Reusable Object-Oriented Software”, Addison-Wesley. [Lar98] Larman, C. “Applying UML and Patterns”, Prentice Hall. [Mar95] Martin, R.C. “Designing Object-Oriented Applications using the Booch Method”, Prentice-Hall. [Oli86] Olivé, A. “A comparison of the operational and deductive approaches to conceptual information systems modelling” , Information Processing 86, H.-J. Kugler (ed.), pp 91-96 [Rie96] Riehle, D. “The Event Notification Pattern - Integrating Implicit Invocation with Object Orientation”. TPOS, Vol. 2(1), pp. 43-52. [Sha96] Shaw, M.; Garlan, D. “Software Architecture. Perspectives on an emerging discipline”, Prentice Hall. [Sul92] Sullivan, K.J.; Notkin, D. “Reconciling Environment Integration and Software Evolution”, ACM Trans. Softw. Eng. and Methodologies, Vol. 1, No. 3, July, pp. 229-268. [Sul96] Sullivan, K.J.; Kalet, I.J.; Notkin, D. “Evaluating the mediator method: Prism as a case study”, IEEE Transactions on Software Engineering, Vol. 22, No. 8, August, pp. 563-579 [Wid96] Widom J.; Ceri, S. “Active Database Systems”, Morgan-Kaufmann.
37 Índex de Figures. Figura 3.1: Diagrama de classes d'objectes.................................................................................3 Figura 3.2: Diagrama de classes d'esdeveniments......................................................................3 Figura 3.3: Diagrama seqüència SaldoCompte...........................................................................4 Figura 3.4: Diagrama seqüència OmplirCaixer ..........................................................................4 Figura 3.5: Diagrama seqüència IngrésEnCaixer .......................................................................5 Figura 3.6: Diagrama seqüència Confirmar................................................................................5 Figura 3.7: Diagrama seqüència Ingrés.......................................................................................5 Figura 3.8: Diagrama de classes d'esdeveniments externs..........................................................6 Figura 3.9: Diagrama seqüència ReEstalvi.................................................................................6 Figura 3.10: Diagrama seqüència ReCorrent..............................................................................7 Figura 4.1: Esquema general de funcionament...........................................................................8 Figura 4.2: Diagrama de classes d’esdeveniments......................................................................9 Figura 4.3: Comunicació d’esdeveniment ................................................................................10 Figura 4.4: Sintaxi d'una subscripció........................................................................................11 Figura 4.5: Sintaxi abreviada d'una subscripció .......................................................................12 Figura 4.6: Esquema general des del punt de vista del GE.......................................................13 Figura 5.1: Diagrama de classes d'objectes...............................................................................13 Figura 5.2: Diagrama de classes d'esdeveniments....................................................................14 Figura 5.3: Diagrama de classes d'esdeveniments externs........................................................14 Figura 5.4: Diagrama de classes d'esdeveniments generats......................................................15 Figura 5.5: Diagrama de seqüència SaldoCompte....................................................................16 Figura 5.6: Diagrama de seqüència OmplirCaixer....................................................................16 Figura 5.7: Diagrama de seqüència IngrésEnCaixer.................................................................17 Figura 5.8: Diagrama de seqüència Confirmar (primera versió) ..............................................17 Figura 5.9: Diagrama seqüència Confirmar (segona versió) ....................................................18
38 Figura 5.10: Diagrama seqüència Ingrés (primera versió)........................................................19 Figura 5.11: Diagrama seqüència Ingrés (segona versió).........................................................19 Figura 5.12: Diagrama seqüència ReEstalvi (cas d’independència).........................................20 Figura 5.13: Diagrama seqüència ReEstalvi (cas de dependència)...........................................20 Figura 5.14: Diagrama seqüència ReCorrent (cas d’independència)........................................21 Figura 6.1: Diagrama seqüència Ingrés (invocació explícita)...................................................31 Figura 6.2: Diagrama seqüència Ingrés (invocació implícita)..................................................32 Figura 6.3: Diagrama seqüència RegalBanc (invocació explícita)...........................................33 Figura 6.4: Diagrama seqüència RegalBanc (invocació implícita)...........................................34 Índex de Taules. Taula 4.1: Correspondència entre tipus d'esdeveniments ...........................................................8 Taula 6.1: Resultats de la mètrica WMC..................................................................................25 Taula 6.2: Resultats de la mètrica DIT .....................................................................................26 Taula 6.3: Resultats de la mètrica NOC....................................................................................27 Taula 6.4: Resultats de la mètrica CBO....................................................................................28 Taula 6.5: Resultats de la mètrica RFC ....................................................................................29 Taula 6.6: Resultats de la mètrica LCOM ................................................................................30