SlideShare ist ein Scribd-Unternehmen logo
1 von 13
Introducció<br />Aquesta guia d’estil de programació té com a objectiu, que tots els codis de software realitzats en els diversos departaments de La Salle segueixin un mateix estil, ja siguin projectes grans o petits. <br />Un guia d’aquest tipus es fa necessària, sobretot, en els projectes d’equip on hi treballen diverses persones, doncs malgrat les diverses mans que els programen, el resultat final ha de ser un codi que aparentment ha estat fet per unes soles mans, i que segueixi una única lògica.<br />Aquesta guia es basa en les principals convencions de codi dels principals llenguatges de programació, com són Java (Java Code Conventions) o C (MISRA C).<br />Finalment, aclarir que seguir una guia d’estils no va renyit amb aplicar les particularitats de cada un dels diferents llenguatges, doncs aquestes se sobreposen a qualsevol guia.<br />Requeriments<br />Tots els requeriments d’un projecte han d’estar centralitzats en una mateixa ubicació de fàcil accés i actualització per part de tots els membres de l’equip col·laborador.  <br />1.1 Llenguatge<br />Cada requeriment haurà de contenir, com a mínim la següent informació:<br />Un identificador que permeti fer-hi una referència inequívoca per part de l’equip de desenvolupament del projecte.<br />La descripció del requeriment.<br />El nom de la persona que ha anotat aquest requeriment.<br />El nom de la persona que , per part del client, ha ordenat aquest requeriment.<br />Requeriment dels quals depèn.<br />El format dels requeriments ha de ser:<br />Clar i sense ambigüitats.<br />Consistent amb la resta de requeriments i no redundant.<br />Verificable i modificable.<br />Ha de tenir definida una prioritat respecte la resta de requeriments del projecte.<br />En les descripcions dels requeriments mai s’han d’utilitzar expressions vagues i poc concretes com ara lent, ràpid, molt de temps, típicament, quasi sempre, pocs cops ...<br />S’ha de respectar, en la mesura del possible, la terminologia emprada per part del client, per tal de poder mantenir una bona negociació.<br />Sempre que sigui possible s’expressarà de forma positiva<br />Utilitzarem: El procés A ha de realitzar la tasca B en 5 segons o menys.<br />No utilitzarem :  El procés A  no ha de tardar mes de 5 segons en realitzar la tasca B.<br />3.2 Requisits precisos<br />Tots els requeriments que facin referència a magnituds físiques hauran d’indicar les unitats de mesures i els marges d’error.<br />Tots els requeriments que afectin a resultats visuals hauran d’especificar clarament les dades que es volen mostrar, l’ordenació i sentit i el seu format de sortida.<br />Tots els requeriments relacionats amb la interfície de sistemes externs han d’indicar el format d’intercanvi, els protocols, els temps de vida i el tractament de les situacions d’error.<br />Nomenclatura<br />A continuació s’exposen un seguit de regles bàsiques de nomenclatura aplicables a qualsevol tipus d’identificador. Classes, taules i camps  de bases de dades,  variables, mètodes...<br />Totes les variables d’un projecte han seguir una mateixa lògica d’idioma que s’ha d’acordar al començament del projecte amb tots els membres de l’equip.<br />No s’utilitzaran  guions baixos “ _ “ en els noms dels identificadors,  tret de les constants i els identificadors generats automàticament per generadors de codi.<br />No s’utilitzaran noms, la única diferencia dels quals sigui numeral. P.e Fitxer1, Fitxer2.<br />No es farà ús de la capitalització per distingir identificadors.<br />Les següents partícules estan prohibides en els noms d’identificadors:<br />Determinants de qualsevol tipus: el, la, jo, teu  aquest, triple,  segon, un...<br />Pronoms de qualsevol tipus: jo, tu ,ell, aquest...<br />Les úniques excepcions d’aquesta regla són l’ordinal “primer” i el multiplicatiu “doble”.<br />No s’utilitzaran ni sufixes ni prefixes amb l’únic objectiu d’indicar el tipus d’identificador. P.e classeExemple, varExemple, enumOpcions, metodeSuma...<br />No es recomanable l’ús de conjuncions o preposicions dins d’un nom d’identificador.<br />En tot moment s’utilitzaran noms clars, descriptius i lliures d’ambigüetats.<br />P.e farem servir “dataPeticioClient enlloc de “data” o “estatPantalla” enlloc d’”estat”.<br />3.Classes<br />3.1 Disseny de classes<br />A l’hora de fer el disseny d’una classe mai s’ha d’anticipar la creació d’una futura classe dependent de la que en volem fer el disseny en qüestió. Per tant, la nostra classe s’haurà de limitar a realitzar la funció que volem cobrir. L’Herència queda exclosa d’aquesta anticipació, doncs en aquest cas estarem pensant en una abstracció.<br />S’han de procurar evitar les classes amb funcionalitats molt limitades i que no representen un objecte en sí. Aquest tipus de classe acostumen a aportar confusió dins d’un projecte ja que mai queda massa clara la finalitat de la seva creació.<br />Les classes han de modelar preferentment objectes del món real o abstraccions d’aquests. Només en justificades ocasions, es poden crear classes amb la finalitat d’aïllar complexitat d’implementació dins del codi.<br />La robustesa d’una classe varia en funció de la seva immutabilitat. La immutabilitat es reforça amb:<br />Declaració de tots els seus camps com privats i no heretables.<br />Supressió de mètodes modificadors poc útils.<br />En la mesura del possible, fer la classe com a no extensible.<br />3.2 Herència<br />Una classe s’ha de dissenyar pensant en si tindrà herència o bé no serà hedreable, no hi ha un punt mitjà.<br />DIT (Depht of Inheritance Tree) es defineix com la longitud més llarga de la cadena d’herència respecte el punt on ens trobem actualment. Un DIT superior a 3 serà sinònim d’un alt nombre de falles en la nostra implementació.<br />Les jerarquies de classe que tenen un únic fill són sempre sospitoses. <br />No es admissible el disseny de jerarquies amb un DIT superior a 7.<br />3.3 Nomenclatura<br />Les classes representes COSES, no accions, així doncs cada classe tindrà per nom un nom en el sentit gramatical, i MAI un verb.<br />Les classes que representen Excepcions acabaran amb el sufix “Exception”.<br />Els noms de les classes estaran en singular, exceptuant els casos en que la classe representi múltiples coses.<br />Un nom de classe mai donarà pistes sobre la implementació interna de la mateixa.<br />4.Enumeracions<br />El nom de les enumeracions sempre estarà en singular.<br />El nom dels membres de les enumeracions estarà en majúscules i separant les diferents paraules amb guió baix (_).  <br />Es recomanable dotar a les enumeracions d’una propietat descriptiva en el propi nom.<br />5.Rutines i mètodes<br />5.1 Nombre de mètodes i graus de responsabilitat<br />Import Coupling (IC) es defineix com el nombre d’interaccions entre la classe actual i totes les classes amb les que interacciona.<br />Existeix una alta relació entre l’ IC i el nombre de fallades d’una classe. Així doncs, el nombre d’interaccions ha d’ésser limitat. (Briand, 1998).<br />El nombre de mètodes d’una classe ha de ser inferior a 40 (Rosenberg, Stapko y Gallo, 1999) .<br />5.2 Nomenclatura<br />Un bon nom per a un mètode es aquell que descriu tot el que el mètode fa.<br />Es recomana que els noms dels mètodes que no retornen valor (“procediments”) consisteixin en un verb seguit del objecte a que afecta el verb. <br />p.e CalcularIPC, ImprimirMenu.<br />El nom de les funcions que retornen valor han de descriure aquest valor.<br />p.e IPC, MenuComplet.<br />Es perillós incloure en el nom detalls sobre la implementació interna del procediment, mètode o classe.<br />No es farà ús de verbs generals per anomenar rutines.<br />p.e GestionarClient, ProcessarPetició, ManegaTaula.<br />No es farà ús tampoc de noms genèrics com Entrada, Sortida, Dades, que no descriguin ni quin tipus d’objecte estem tractant, ni el format de les dades d’entrada o sortida....<br />p.e ImprimirInforme, MostraSortida, EntraDades.<br />Si treballem amb un conjunt de funcions que realitzen operacions similars amb petites diferencies s’ha d’establir un sistema de creació de noms coherent.<br />p.e Enlloc d’anomenar a una funció “Llegir”, li direm LlegirCaràcter, LlegirLinea o LlegirFrase segons la seva funcionalitat.<br />FALTA ELS NOMS DE PROGRESSSSSSS<br />5.3 Cohesió<br />El terme cohesió fa referència a la força amb la que diverses parts d’una rutina estan relacionades entre si. Per exemple, la funció cos() es altament cohesiva perquè només realitza una tasca. Per altra banda, la funció cosYlogaritme() es dèbilment cohesiva perquè realitza dos funcions que no tenen res a veure l’una amb l’altre.<br />Hi ha diferents tipus de cohesió, alguns dels quals són poc acceptables en una bona programació.<br />Cohesions recomanables:<br />Cohesió funcional. Relació que existeix quan la rutina realitza una única operació.<br />p.e: Sin(), ImprimirIVA(), LlegirNomClient().<br />Cohesió seqüencial. Es dona quan la rutina conté elements que s’ha d’executar en un ordre específic i comparteixen dades. Per exemple, una rutina que obre un fitxer, llegeix unes dades i calcula un total te dos passos amb cohesió seqüencial: El primer lectura de les dades i el segon càlcul del total.<br />Cohesió comunicativa. Cohesió que es dona quan la única relació entre dos passos dins d’una rutina són les dades sobre les que s’opera. Es acceptable ja que normalment es treballa sobre una única estructura de dades. <br />p.e LlegeixNomClientYTelefon. Operarà sobre la estructura Client.<br />Cohesions perilloses:<br />Cohesió temporal. Es dona quan les operacions d’una rutina es realitzen al mateix temps en l’escala del programa. Per exemple, InicialitzarSistema() és una rutina amb cohesió temporal, doncs les seves operacions es realitzen en la fase d’Inicialització.<br />Cohesió lògica. La trobem en el moment que una rutina pot efectuar diferents operacions depenent d’un paràmetre de control. Per exemple: LlegirDades( int quinaDada). Normalment aquestes rutines tenen una estructura interna de switch o if-else, que engloba parts que no tenen res a veure entre sí.<br />Cohesions no acceptables:<br />Cohesió operacional. Es dona quan els diferents passos d’una rutina s’han d’executar d’una forma temporal específica, però, a diferencia de la cohesió seqüencial, no fa referencia al mateix conjunt de dades. <br />p.e ImprimirPagina1yPagina2.<br />Cohesió coincidental.  Les diferents operacions d’una rutina no tenen res a veure entre sí. És sinònim d’absència total de cohesió.<br />UNA BONA RUTINA HA DE TENIR UN ALT GRAU DE COHESIÓ.<br />5.4 Aïllament de codi<br />Aïllarem en rutines els següents aspectes d’un programa:<br />Àrees de canvi probable o freqüent.<br />Operacions amb dades complexes.<br />Segments de codi amb algorismes o lògica complexa.<br />Codi que utilitzi particularitats del computador, sistema operatiu o llenguatge.<br />Les àrees de canvi probable o freqüent poden ser:<br />Dependencies del Hardware.<br />Entrada/Sortida.<br />Àrees de difícil disseny.<br />Variables d’estat.<br />Limitacions en el tamany de les dades.<br />Àrees de programació relacionades amb estructura de processos empresarials. <br />5.5 Acoblament <br />Un grau d’acoblament baix significa que dues rutines son relativament independents entre sí: La modificació d’una d’elles no afectarà a l’altre. Pel contrari un grau d’acoblament alt significa que dues rutines depenen l’una de l’altre.<br />Existeixen diferents graus d’acoblament, a continuació s’exposen els NO Problemàtics:<br />Acoblament per dades simples. L’únic intercanvi d’informació que existeix entre dues rutines és una llista de paràmetres no estructurats. Per exemple, la funció tan(angle) por cridat dins seu a sin(angle) o cos(angle).<br />Acoblament simple per objectes. Un subsistema està acoblat de forma simple a un objecte si en crea una instància. <br />Acoblament de lectura-lectura  per dades globals. Es dona quan dues rutines llegeixen de les mateixes dades globals.<br />Els tipus d’acoblament perillosos són:<br />Acoblament incomplet per dades estructurades. Es dona quan una rutina utilitza només una petita part de l’objecte que instancia. Només es permissible si la rutina té previsió d’acabar usant tota la estructura.<br />Acoblament de control. Una rutina crida a una segona especificant la operació que ha de realitzar per mitjà d’un paràmetre de control.<br />Acoblament de lectura-escriptura  per dades globals. Dues rutines llegeixen i escriuen les mateixes dades globals. <br />Acoblament semàntic.  Un mòdul A fa ús d’informació no pública d’un mòdul B en la seva interacció amb aquest.<br />Acoblament patològic. Una rutina modifica el codi o les dades locals d’una segona.<br />UNA BONA RUTINA HA DE TENIR UN GRAU BAIX D’ACOBLAMENT.<br />5.6 Codificació<br />No existeix una relació demostrada entre la longitud d’una rutina y la seva eficiència o nombre de defectes.<br />Es recomana que una rutina no s’allargui més  de 80 línies de codi.<br />No són recomanables les rutines de mes de 200 línies.<br />Si un bloc de codi o mètode necessita un comentari interior, s’ha de plantejar la possibilitat de constituir un rutina a part amb una contracció del comentari com a nom.<br />Si un bloc de codi deixa de ser útil s’eliminarà totalment i no es deixarà comentat “per si de cas”.<br />Tot mètode ha d’ésser emprat per algú.<br />5.7 Paràmetres<br />Els paràmetres d’una rutina han d’estar ordenats de la següent manera:<br />Paràmetres d’entrada o només lectura.<br />Paràmetres transport o lectura/escriptura.<br />Paràmetres exclusivament de sortida.<br />Si diverses rutines usen paràmetres similars, l’ordre en la llista de paràmetres ha de ser coherent. Per exemple, moltes de les funcions de l’API de Windows requereixen d’un Handle com a paràmetre. Aquest, sempre serà el primer de la llista.<br />Tot els paràmetres que es passen a una funció han d’ésser emprats per aquesta.<br />Els paràmetres Resultat – Estat, sempre han de ser els útims.<br />Els paràmetres mai s’utilitzaran com a variables temporals dins d’una funció.<br />A tall d’exemple, el següent fragment de codi es inadmissible:<br />int operacio (a, b){<br />a :=  b+1;    X <br />b:= a/3;<br />a:=a+b;<br />}<br />Només s’acceptarà aquest cas per a realitzar una normalització del paràmetre d’entrada. P.e  cadena := cadena.toUpperCase.<br />Un nombre màxim recomanat de paràmetres per una rutina és 7. Un nombre superior dificulta enormement la comprensió funcional de la rutina. <br />Un bon disseny per a una rutina es aquell que conté la retenció les seves pròpies fallades i les dels nivells inferiors. Això no vol dir ignorar sinó tractar i actuar en conseqüència els errors obtinguts.<br />Cap rutina es dissenyarà assumint un pas de paràmetres concret.<br />Cap rutina es programarà assumint un tipus de crida concret ( llunyana, propera, per interrupció...).<br />5.8 Valors de retorn<br />Totes les funcions que retornin qualsevol tipus d’estructura de dades, retornaran una estructura buida per indicar absència de resultats i mai NULL.<br />Sempre que retornem cadenes s’ha de documentar si són per ús humà o per a ús per part d’altres processos.<br />Mai s’utilitzarà un retorn per a consum humà per a prendre decisions de procés dins d’una rutina. Un cas particular seria emprar la funció .toString de Java sobre un objecte, per tal d’extreure informació dins d’un procés.<br />6 Mòduls (Packages i Namespaces)<br />6.1 Creació<br />Els mòduls serveixen per aïllar  conjunts de classes molt relacionades entre sí i que col·laboren per tal d’aconseguir un objectiu o funcionalitat comú. Un mòdul pot ser un package en Java o un namespace en c++/.Net.<br />S’haurà de seguir una perspectiva modular i d’ocultació d’informació en qualsevol desenvolupament. Això últim vol dir que la informació ha d’estar molt cohesionada amb les funcions que la tracten, i no ser visible des de l’exterior.<br />No es podrà accedir mai a les interioritats d’una estructura abstracta, sinó que crearem funcions per a fer-ho:INCORRECTE:   Client := Client.^next. { LLISTA ORDENADA }CORRECTE:       Client := ObtenirSegClient(Client); <br />6.2 Nomenclatura<br />La nomenclatura dels mòduls es farà de la següent manera:<br />com.empresa.projecte.component1.component2<br />on component2 sempre serà opcional i component1 serà opcional en projectes que continguin menys de 15 classes.<br />7 Tipus de dades i variables<br />7.1 Definició de tipus de dades<br />Tot i que el llenguatge ens ho permeti, no es redefiniran tipus estandards.<br />p.e  typedef integer longint;<br />S’evitarà en la mesura del possible, la declaració implícita de variables, ja que és sinònim de no declaració i dificulta la comprensió del codi.<br />S’evitarà la modificació del tipus d’una variable durant l’execució tot i que el llenguatge ho permeti.<br />7.2 Noms de variables<br />Igual que amb les rutines, el nom recomanat per a una variable no excedirà els 16 caracters. Es nombraran les variables, acord amb el seu significat i mai acord amb el seu tipus.<br />Es procuraran evitar les variables com i, a, j , n en bucles, independentment de la mida d’aquest.<br />Tret dels llenguatges amb comprovació de tipus dèbil (Pascal, C) ,en l’actualitat la Notació Húngarà ha quedat obsoleta i el seu ús queda limitat a la I capital per a la definició d’interfícies. (IClonable, ISerializable, etc.).<br />Els noms de macros començaran sempre amb (_) i les diferents paraules que els composin també aniran separades amb (_). P.e  _MAX_ALUMNES<br />No s’utilitzaran noms ambigus per a la definició de variables. P.e “Col” pot significar columna o color.<br />7.3 Variables d’estat i temporals<br />Per a designar variables d’estat s’utilitzaran noms que facin referencia a l’objecte que impliquen i l’estat en concret. És a dir, utilitzarel ImpressoraActiva enlloc d’ EstatImpressora o LlumVerda enlloc de EstatLlum.<br />No es aconsellable la paraula Estat dins d’una variable ja que normalment indica el tipus de la variable però es poc descriptiu en quant a funció.<br />No s’empraran noms de l’estil tmp , tmp1, temp, per a designar variables temporals.<br />Es desaconsella l’ús de booleans com a variables d’estat. És preferible l’ús d’enumeracions amb els valors definits com a constants.<br />7.3 Variables booleanes<br />Les variables booleanes han de tenir noms que sugereixin respostes o continguts dels tipus SI/NO. P.e Exit, Correcte, Acabat<br />Els noms sempre han de ser positius. Trobat enlloc de NoTrobat.<br />No són recomanables per als casos en que una variable pot prendre dos valors però aquests no són verdader o fals. P.e Sexe, BlancNegre.<br /> Quan una variable booleana pugui prendre el valor null, no s’intentarà comprendre com funciona la combinació d’aquest valors amb els booleans. És a dir, no s’intentaran extreure regles generalistes de l’estil true or null , false or null ... sinó que tractarem cada cas de forma aïllada.<br />7.4 Arrays i cadenes<br />Es recomanable tractar els arrays com a estructures seqüencials. És a dir, estructures en les que no es pot accedir a l’element N si abans no s’ha passat per N-1 i N-2. L’accés indiscriminat a un array es similar a l’ús de “goto” dins d’un bloc de codi.<br />Aquesta recomanació té validesa sempre i quant l’array sigui homogeni en quant a les dades que conté.<br />Sempre s’evitaran, en la mesura del possible, les declaracions de mida d’array per mitjà de constants literals. Es procurarà fer ús de constants prèviament definides:<br />p.e INCORRECTE     vector =  new array[100];<br />CORRECTE         vector = new array[_MIDA_VECTOR];<br /> 7.5 Punters<br />Tots els punters s’inicialitzaran a null sempre i quan no tinguin una assignació immediata després de la seva declaració.<br />Es convenient restringir l’ús de punters en rutines d’alt nivell.<br />No es permeten més de dues de-referències per punter:<br />p.e  Llista.*Seguent.*Anterior.*Anterior = NULL ;<br />Excepte que s’estigui treballant amb objectes, s’evitaran les conversions de tipus de tipus punter.<br />7.6 Inicialització i ús<br />No es farà ús de valors amagats  en les variables. Per exemple, PaginesImpreses són el nombre de pàgines que s’ha imprès i -1 si hi ha hagut algun error.<br />Quan existeixin variables globlas, s’evitarà l’accés directe per diverses rutines. P.e enlloc de fer Pagina++, totes les rutines cridaran al mètode AugmentarPagina.<br />No s’ha de fer ús de valors directes en els programes.  Qualsevol nombre o cadena constant ha d’ésser substituïda per una constant amb nom. Exceptuant els següents casos:   0 , 1/ -1, 2/-2, true/false, “ “.<br />Les divisions han d’estar protegides per al cas en que el divisor sigui zero.<br />Per a tots els valors de retorn NULL, se n’ha d’especificar el seu significat.<br />No es crearan rutines que retornin null amb significats polivalents.<br />8 Estructures de control<br />8.1 Flux lineal<br />Quan un grup de sentencies s’han d’executar en un ordre concret, la dependencia de l’ordre ha de ser obvia.<br />p.e  Inicialitzar()<br />InicialitzarImpressora()<br />Suposant que Inicialitzar() declara variables globals que han de ser emprades per la segona funció, es podria pensar que son rutines independents l’una de l’altre i que l’ordre no és crucial. Així doncs, la nomenclatura correcte serà:<br />InicialitzarDadesGlobals()<br />IncialitzarImpressora()<br />D’aquesta manera ja s’aprecia que les dades globals són el primer que s’han de declarar.<br />El codi ha de ser llegible de dalt a baix. Quan les crides a funció no depenguin entre si, s’agruparan a nivell de dades tractades i no a nivell d’operació.<br />Agrupant a nivell de funció, es pot trobar un codi com el següent:<br />IniDadesMensuals()<br />IniDadesSemanals()<br />IniDadesDiaries()<br />CalcDadesmensuals()CalcDadesSemanals()CalcDadesDiaries()<br />En canvi, la forma correcta amb agrupació per dades seria:<br />IniDadesMensuals()<br />IniDadesSemanals()<br />IniDadesDiaries()<br />CalcDadesmensuals()<br />CalcDadesSemanals()CalcDadesDiaries()<br />Es defineix l’obertura d’una variable com a el nombre de línies entre dues referències consecutives a la variable. P.e<br />a := 0<br />b := 0               obertura<br />c := 0<br />a:= b + c<br />S’ha de procurar mantenir una obertura baixa de cada variable en un mòdul.<br />Amb els llenguatges que permetin declarar variables en qualsevol punt del programa, sempre es faran les declaracions al punt més proper al seu primer ús.<br />Les variables sempre tindran el temps de vida més curt possible.<br />8.2 Flux condicional<br />No s’utilitzaran nivells d’aniuament superiors a 4, excepte en condicionals del tipus<br />If ...... Then<br />Else If ..... ThenElse If ..... Then<br />Else If ..... ThenElse ...... ;<br />Mai s’utilitzaran clàusules “Then” buides, usant la funcionalitat de la sentencia Else.<br />Les expressions condicionals complexes, s’han de simplificar fent ús de booleans temporals o funcions booleanes.<br />En una expressió booleana que enumeri diversos casos, els casos més freqüents sempre encapçalaran la funció:<br />Pe.        IF esLletra(char) || esSignePuntuacio || esDigit  Then ......<br />En els llenguatges on existeixi l’operador condicional, no s’utilitzaran operadors ?: aniuats.<br />No s’utilitzaran variables falses (ni fer malabarismes) per emprar la funció switch enlloc d’un if-else.<br />EntradaTeclat := LlegirEntradaTeclat()<br />Switch (EntradaTeclar.charAt(2))<br />Case ‘a’: copia(); break;<br />Case ‘b’: enganxa; break; ....<br />No s’utilitzarà el fall-through dins d’un switch. Si un fragment de codi es repeteix, replicarem el codi, i si és molt gran, el seu lloc es dins d’una rutina.<br />Aquest fragment de codi es inadmissible:<br />Switch (Token)<br />Case ‘Token1’:  ................... ;<br />.........................;<br />Case ‘Token2’: ..............; break;<br />.....<br />Si un switch fa referència a un tipus enumerat, considerarà tots els casos d’aquest tipus.<br />No s’utilitzaran comparacions explícites amb booleans:<br />p.e Farem iF(esCorrecte) enlloc de IF(esCorrecte == true)<br />En estructures de control de tipus if-else, el cas positiu sempre anirà dins del IF.<br />8.2 Flux iteratiu<br />Es recomanable tractar l’interior d’un bucle com a rutina o caixa negra, aplicant tot el que s’ha comentat sobre acoblament i cohesió amb la resta de codi.<br />Les condicions inicials i de finalització d’un bucle han de ser clares, sense que faci falta examinar l’interior del bucle per entendre’n el funcionament.<br />Quan un bucle sigui infinit, es recomanable anunciar-ho quan abans. Així doncs farem while(true) enlloc de  Do ....... while(true).<br />S’han d’evitar bucles de cos buit, exceptuant aquells casos tant trivials que es puguin llegir com a frase. P.e <br />Do while (!KeyPressed)<br />Definim l’obertura d’un bucle com al nombre de línies que ocupa. Un cop més aquesta s’ha de mantenir baixa.<br />La longitud màxima recomanada per a un bucle és de 66 línies.<br />Dins dels bucles FOR, s’ha d’evitar aquell codi que depengui d’un valor concret de l’index de control.<br />p.e       for(int posicio=0; posicio < MAX_POSICIO; posicio ++){<br />if(posicio == POSICIO_ESPECIAL)<br />...........<br />}<br />No s’utilitzarà el valor d’un índex de control fora del bucle que controla.<br />No s’utilitzarà un aniuament de bucles superior a 3.<br />No s’utilitzaran bucles amb més d’una variable d’iteració<br />p.e  for(int a, int b; ...........; a++, b+=2)<br />8.2 Flux recursiu<br />S’evitarà l’ús de recursivitat si existeix una solució iterativa igual de llegible.<br />La llegibilitat serà l’únic criteria a considerar exceptuant que el propi programa indiqui certs requisits de rendiment, tamany en memòria, etc-<br />Es defineix l’obertura de la recursió com al nombre de rutines que hi ha entremig fins que es tanca el bucle recursiu. Per exemple, si A crida a B, B crida a C y C crida a A, l’obertura es 2 (B i C).<br />No es recomanable una obertura superior a 2.<br />Quan es faci ús d’aquest tipus d’algorismes s’haurà de controlar que hi hagi prou memòria a la pila.<br />8.3 Complexitat<br />Definim la complexitat ciclomàtica de McCabe com el nombre possible de camins diferents en un programa ( Software Engineering Insitute, Carnegie-Mellon 2000).<br />Una forma de calcular la complexitat de McCabe d’un programa és:<br />Començar amb una complexitat 1.<br />Afegir 1 per cada if,while,do-while, for, and, or,xor,?: i cada un dels casos d’un switch.<br />La complexitat s’evaluarà de la següent manera:<br />0 – 7 . Complexitat acceptable.<br />8 –15. Seria convenient simplificar la rutina.<br />15+   . S’ha de dividir la rutina.<br />
Guia d'estils jordi
Guia d'estils jordi
Guia d'estils jordi
Guia d'estils jordi
Guia d'estils jordi
Guia d'estils jordi
Guia d'estils jordi
Guia d'estils jordi
Guia d'estils jordi
Guia d'estils jordi
Guia d'estils jordi
Guia d'estils jordi

Weitere ähnliche Inhalte

Ähnlich wie Guia d'estils jordi

Programació - Pràctica1 - Lidia Bria
Programació - Pràctica1 - Lidia BriaProgramació - Pràctica1 - Lidia Bria
Programació - Pràctica1 - Lidia BriaLidia Bria
 
El framework Cakephp
El framework CakephpEl framework Cakephp
El framework Cakephpherotyc
 
Sistema informatic
Sistema informaticSistema informatic
Sistema informaticEdu Alias
 
Validació de Documents XML amb XSD
Validació de Documents XML amb XSDValidació de Documents XML amb XSD
Validació de Documents XML amb XSDXavier Sala Pujolar
 
Programació - PAC 1 correcció - Multimèdia (UOC) - Paquita Ribas
Programació - PAC 1 correcció - Multimèdia (UOC) - Paquita RibasProgramació - PAC 1 correcció - Multimèdia (UOC) - Paquita Ribas
Programació - PAC 1 correcció - Multimèdia (UOC) - Paquita RibasPaquita Ribas
 
Programació Web - PAC 4 correcció - Multimèdia (UOC) - Paquita Ribas
Programació  Web - PAC 4 correcció - Multimèdia (UOC) - Paquita RibasProgramació  Web - PAC 4 correcció - Multimèdia (UOC) - Paquita Ribas
Programació Web - PAC 4 correcció - Multimèdia (UOC) - Paquita RibasPaquita Ribas
 
Programació - Pràctica 1 correcció - Multimedia (UOC) - Paquita Ribas
Programació - Pràctica 1 correcció - Multimedia (UOC) - Paquita RibasProgramació - Pràctica 1 correcció - Multimedia (UOC) - Paquita Ribas
Programació - Pràctica 1 correcció - Multimedia (UOC) - Paquita RibasPaquita Ribas
 
Itineraris IT Academy (2020)
Itineraris IT Academy (2020)Itineraris IT Academy (2020)
Itineraris IT Academy (2020)Barcelona Activa
 
Patrons grasp
Patrons graspPatrons grasp
Patrons graspelpatxi
 
Administració i gestió d'organitzacions - Pac1 - Lidia Bria
Administració i gestió d'organitzacions - Pac1 - Lidia BriaAdministració i gestió d'organitzacions - Pac1 - Lidia Bria
Administració i gestió d'organitzacions - Pac1 - Lidia BriaLidia Bria
 
Programació - Pràctica 1 - Multimedia (UOC) - Paquita Ribas
Programació - Pràctica 1 - Multimedia (UOC) - Paquita RibasProgramació - Pràctica 1 - Multimedia (UOC) - Paquita Ribas
Programació - Pràctica 1 - Multimedia (UOC) - Paquita RibasPaquita Ribas
 
Transformació model entitat-relació al model relacional
Transformació model entitat-relació al model relacionalTransformació model entitat-relació al model relacional
Transformació model entitat-relació al model relacionalMiquel Boada Artigas
 
Exercicisdeltema3
Exercicisdeltema3 Exercicisdeltema3
Exercicisdeltema3 claraaoriley
 
Programació Web - PAC 2 correcció - Multimèdia (UOC) - Paquita Ribas
Programació  Web - PAC 2 correcció - Multimèdia (UOC) - Paquita RibasProgramació  Web - PAC 2 correcció - Multimèdia (UOC) - Paquita Ribas
Programació Web - PAC 2 correcció - Multimèdia (UOC) - Paquita RibasPaquita Ribas
 

Ähnlich wie Guia d'estils jordi (20)

Programació - Pràctica1 - Lidia Bria
Programació - Pràctica1 - Lidia BriaProgramació - Pràctica1 - Lidia Bria
Programació - Pràctica1 - Lidia Bria
 
PW_pac1
PW_pac1PW_pac1
PW_pac1
 
El framework Cakephp
El framework CakephpEl framework Cakephp
El framework Cakephp
 
UD3 PROGRAMACIÓ
UD3 PROGRAMACIÓUD3 PROGRAMACIÓ
UD3 PROGRAMACIÓ
 
UD3 Programació
UD3 ProgramacióUD3 Programació
UD3 Programació
 
Sistema informatic
Sistema informaticSistema informatic
Sistema informatic
 
Model entitat relació (ER)
Model entitat relació (ER)Model entitat relació (ER)
Model entitat relació (ER)
 
Validació de Documents XML amb XSD
Validació de Documents XML amb XSDValidació de Documents XML amb XSD
Validació de Documents XML amb XSD
 
Programació - PAC 1 correcció - Multimèdia (UOC) - Paquita Ribas
Programació - PAC 1 correcció - Multimèdia (UOC) - Paquita RibasProgramació - PAC 1 correcció - Multimèdia (UOC) - Paquita Ribas
Programació - PAC 1 correcció - Multimèdia (UOC) - Paquita Ribas
 
Programació Web - PAC 4 correcció - Multimèdia (UOC) - Paquita Ribas
Programació  Web - PAC 4 correcció - Multimèdia (UOC) - Paquita RibasProgramació  Web - PAC 4 correcció - Multimèdia (UOC) - Paquita Ribas
Programació Web - PAC 4 correcció - Multimèdia (UOC) - Paquita Ribas
 
Programació - Pràctica 1 correcció - Multimedia (UOC) - Paquita Ribas
Programació - Pràctica 1 correcció - Multimedia (UOC) - Paquita RibasProgramació - Pràctica 1 correcció - Multimedia (UOC) - Paquita Ribas
Programació - Pràctica 1 correcció - Multimedia (UOC) - Paquita Ribas
 
Itineraris IT Academy (2020)
Itineraris IT Academy (2020)Itineraris IT Academy (2020)
Itineraris IT Academy (2020)
 
Patrons grasp
Patrons graspPatrons grasp
Patrons grasp
 
Administració i gestió d'organitzacions - Pac1 - Lidia Bria
Administració i gestió d'organitzacions - Pac1 - Lidia BriaAdministració i gestió d'organitzacions - Pac1 - Lidia Bria
Administració i gestió d'organitzacions - Pac1 - Lidia Bria
 
Programació - Pràctica 1 - Multimedia (UOC) - Paquita Ribas
Programació - Pràctica 1 - Multimedia (UOC) - Paquita RibasProgramació - Pràctica 1 - Multimedia (UOC) - Paquita Ribas
Programació - Pràctica 1 - Multimedia (UOC) - Paquita Ribas
 
Prog_prac1
Prog_prac1Prog_prac1
Prog_prac1
 
Python
PythonPython
Python
 
Transformació model entitat-relació al model relacional
Transformació model entitat-relació al model relacionalTransformació model entitat-relació al model relacional
Transformació model entitat-relació al model relacional
 
Exercicisdeltema3
Exercicisdeltema3 Exercicisdeltema3
Exercicisdeltema3
 
Programació Web - PAC 2 correcció - Multimèdia (UOC) - Paquita Ribas
Programació  Web - PAC 2 correcció - Multimèdia (UOC) - Paquita RibasProgramació  Web - PAC 2 correcció - Multimèdia (UOC) - Paquita Ribas
Programació Web - PAC 2 correcció - Multimèdia (UOC) - Paquita Ribas
 

Guia d'estils jordi

  • 1. Introducció<br />Aquesta guia d’estil de programació té com a objectiu, que tots els codis de software realitzats en els diversos departaments de La Salle segueixin un mateix estil, ja siguin projectes grans o petits. <br />Un guia d’aquest tipus es fa necessària, sobretot, en els projectes d’equip on hi treballen diverses persones, doncs malgrat les diverses mans que els programen, el resultat final ha de ser un codi que aparentment ha estat fet per unes soles mans, i que segueixi una única lògica.<br />Aquesta guia es basa en les principals convencions de codi dels principals llenguatges de programació, com són Java (Java Code Conventions) o C (MISRA C).<br />Finalment, aclarir que seguir una guia d’estils no va renyit amb aplicar les particularitats de cada un dels diferents llenguatges, doncs aquestes se sobreposen a qualsevol guia.<br />Requeriments<br />Tots els requeriments d’un projecte han d’estar centralitzats en una mateixa ubicació de fàcil accés i actualització per part de tots els membres de l’equip col·laborador. <br />1.1 Llenguatge<br />Cada requeriment haurà de contenir, com a mínim la següent informació:<br />Un identificador que permeti fer-hi una referència inequívoca per part de l’equip de desenvolupament del projecte.<br />La descripció del requeriment.<br />El nom de la persona que ha anotat aquest requeriment.<br />El nom de la persona que , per part del client, ha ordenat aquest requeriment.<br />Requeriment dels quals depèn.<br />El format dels requeriments ha de ser:<br />Clar i sense ambigüitats.<br />Consistent amb la resta de requeriments i no redundant.<br />Verificable i modificable.<br />Ha de tenir definida una prioritat respecte la resta de requeriments del projecte.<br />En les descripcions dels requeriments mai s’han d’utilitzar expressions vagues i poc concretes com ara lent, ràpid, molt de temps, típicament, quasi sempre, pocs cops ...<br />S’ha de respectar, en la mesura del possible, la terminologia emprada per part del client, per tal de poder mantenir una bona negociació.<br />Sempre que sigui possible s’expressarà de forma positiva<br />Utilitzarem: El procés A ha de realitzar la tasca B en 5 segons o menys.<br />No utilitzarem : El procés A no ha de tardar mes de 5 segons en realitzar la tasca B.<br />3.2 Requisits precisos<br />Tots els requeriments que facin referència a magnituds físiques hauran d’indicar les unitats de mesures i els marges d’error.<br />Tots els requeriments que afectin a resultats visuals hauran d’especificar clarament les dades que es volen mostrar, l’ordenació i sentit i el seu format de sortida.<br />Tots els requeriments relacionats amb la interfície de sistemes externs han d’indicar el format d’intercanvi, els protocols, els temps de vida i el tractament de les situacions d’error.<br />Nomenclatura<br />A continuació s’exposen un seguit de regles bàsiques de nomenclatura aplicables a qualsevol tipus d’identificador. Classes, taules i camps de bases de dades, variables, mètodes...<br />Totes les variables d’un projecte han seguir una mateixa lògica d’idioma que s’ha d’acordar al començament del projecte amb tots els membres de l’equip.<br />No s’utilitzaran guions baixos “ _ “ en els noms dels identificadors, tret de les constants i els identificadors generats automàticament per generadors de codi.<br />No s’utilitzaran noms, la única diferencia dels quals sigui numeral. P.e Fitxer1, Fitxer2.<br />No es farà ús de la capitalització per distingir identificadors.<br />Les següents partícules estan prohibides en els noms d’identificadors:<br />Determinants de qualsevol tipus: el, la, jo, teu aquest, triple, segon, un...<br />Pronoms de qualsevol tipus: jo, tu ,ell, aquest...<br />Les úniques excepcions d’aquesta regla són l’ordinal “primer” i el multiplicatiu “doble”.<br />No s’utilitzaran ni sufixes ni prefixes amb l’únic objectiu d’indicar el tipus d’identificador. P.e classeExemple, varExemple, enumOpcions, metodeSuma...<br />No es recomanable l’ús de conjuncions o preposicions dins d’un nom d’identificador.<br />En tot moment s’utilitzaran noms clars, descriptius i lliures d’ambigüetats.<br />P.e farem servir “dataPeticioClient enlloc de “data” o “estatPantalla” enlloc d’”estat”.<br />3.Classes<br />3.1 Disseny de classes<br />A l’hora de fer el disseny d’una classe mai s’ha d’anticipar la creació d’una futura classe dependent de la que en volem fer el disseny en qüestió. Per tant, la nostra classe s’haurà de limitar a realitzar la funció que volem cobrir. L’Herència queda exclosa d’aquesta anticipació, doncs en aquest cas estarem pensant en una abstracció.<br />S’han de procurar evitar les classes amb funcionalitats molt limitades i que no representen un objecte en sí. Aquest tipus de classe acostumen a aportar confusió dins d’un projecte ja que mai queda massa clara la finalitat de la seva creació.<br />Les classes han de modelar preferentment objectes del món real o abstraccions d’aquests. Només en justificades ocasions, es poden crear classes amb la finalitat d’aïllar complexitat d’implementació dins del codi.<br />La robustesa d’una classe varia en funció de la seva immutabilitat. La immutabilitat es reforça amb:<br />Declaració de tots els seus camps com privats i no heretables.<br />Supressió de mètodes modificadors poc útils.<br />En la mesura del possible, fer la classe com a no extensible.<br />3.2 Herència<br />Una classe s’ha de dissenyar pensant en si tindrà herència o bé no serà hedreable, no hi ha un punt mitjà.<br />DIT (Depht of Inheritance Tree) es defineix com la longitud més llarga de la cadena d’herència respecte el punt on ens trobem actualment. Un DIT superior a 3 serà sinònim d’un alt nombre de falles en la nostra implementació.<br />Les jerarquies de classe que tenen un únic fill són sempre sospitoses. <br />No es admissible el disseny de jerarquies amb un DIT superior a 7.<br />3.3 Nomenclatura<br />Les classes representes COSES, no accions, així doncs cada classe tindrà per nom un nom en el sentit gramatical, i MAI un verb.<br />Les classes que representen Excepcions acabaran amb el sufix “Exception”.<br />Els noms de les classes estaran en singular, exceptuant els casos en que la classe representi múltiples coses.<br />Un nom de classe mai donarà pistes sobre la implementació interna de la mateixa.<br />4.Enumeracions<br />El nom de les enumeracions sempre estarà en singular.<br />El nom dels membres de les enumeracions estarà en majúscules i separant les diferents paraules amb guió baix (_). <br />Es recomanable dotar a les enumeracions d’una propietat descriptiva en el propi nom.<br />5.Rutines i mètodes<br />5.1 Nombre de mètodes i graus de responsabilitat<br />Import Coupling (IC) es defineix com el nombre d’interaccions entre la classe actual i totes les classes amb les que interacciona.<br />Existeix una alta relació entre l’ IC i el nombre de fallades d’una classe. Així doncs, el nombre d’interaccions ha d’ésser limitat. (Briand, 1998).<br />El nombre de mètodes d’una classe ha de ser inferior a 40 (Rosenberg, Stapko y Gallo, 1999) .<br />5.2 Nomenclatura<br />Un bon nom per a un mètode es aquell que descriu tot el que el mètode fa.<br />Es recomana que els noms dels mètodes que no retornen valor (“procediments”) consisteixin en un verb seguit del objecte a que afecta el verb. <br />p.e CalcularIPC, ImprimirMenu.<br />El nom de les funcions que retornen valor han de descriure aquest valor.<br />p.e IPC, MenuComplet.<br />Es perillós incloure en el nom detalls sobre la implementació interna del procediment, mètode o classe.<br />No es farà ús de verbs generals per anomenar rutines.<br />p.e GestionarClient, ProcessarPetició, ManegaTaula.<br />No es farà ús tampoc de noms genèrics com Entrada, Sortida, Dades, que no descriguin ni quin tipus d’objecte estem tractant, ni el format de les dades d’entrada o sortida....<br />p.e ImprimirInforme, MostraSortida, EntraDades.<br />Si treballem amb un conjunt de funcions que realitzen operacions similars amb petites diferencies s’ha d’establir un sistema de creació de noms coherent.<br />p.e Enlloc d’anomenar a una funció “Llegir”, li direm LlegirCaràcter, LlegirLinea o LlegirFrase segons la seva funcionalitat.<br />FALTA ELS NOMS DE PROGRESSSSSSS<br />5.3 Cohesió<br />El terme cohesió fa referència a la força amb la que diverses parts d’una rutina estan relacionades entre si. Per exemple, la funció cos() es altament cohesiva perquè només realitza una tasca. Per altra banda, la funció cosYlogaritme() es dèbilment cohesiva perquè realitza dos funcions que no tenen res a veure l’una amb l’altre.<br />Hi ha diferents tipus de cohesió, alguns dels quals són poc acceptables en una bona programació.<br />Cohesions recomanables:<br />Cohesió funcional. Relació que existeix quan la rutina realitza una única operació.<br />p.e: Sin(), ImprimirIVA(), LlegirNomClient().<br />Cohesió seqüencial. Es dona quan la rutina conté elements que s’ha d’executar en un ordre específic i comparteixen dades. Per exemple, una rutina que obre un fitxer, llegeix unes dades i calcula un total te dos passos amb cohesió seqüencial: El primer lectura de les dades i el segon càlcul del total.<br />Cohesió comunicativa. Cohesió que es dona quan la única relació entre dos passos dins d’una rutina són les dades sobre les que s’opera. Es acceptable ja que normalment es treballa sobre una única estructura de dades. <br />p.e LlegeixNomClientYTelefon. Operarà sobre la estructura Client.<br />Cohesions perilloses:<br />Cohesió temporal. Es dona quan les operacions d’una rutina es realitzen al mateix temps en l’escala del programa. Per exemple, InicialitzarSistema() és una rutina amb cohesió temporal, doncs les seves operacions es realitzen en la fase d’Inicialització.<br />Cohesió lògica. La trobem en el moment que una rutina pot efectuar diferents operacions depenent d’un paràmetre de control. Per exemple: LlegirDades( int quinaDada). Normalment aquestes rutines tenen una estructura interna de switch o if-else, que engloba parts que no tenen res a veure entre sí.<br />Cohesions no acceptables:<br />Cohesió operacional. Es dona quan els diferents passos d’una rutina s’han d’executar d’una forma temporal específica, però, a diferencia de la cohesió seqüencial, no fa referencia al mateix conjunt de dades. <br />p.e ImprimirPagina1yPagina2.<br />Cohesió coincidental. Les diferents operacions d’una rutina no tenen res a veure entre sí. És sinònim d’absència total de cohesió.<br />UNA BONA RUTINA HA DE TENIR UN ALT GRAU DE COHESIÓ.<br />5.4 Aïllament de codi<br />Aïllarem en rutines els següents aspectes d’un programa:<br />Àrees de canvi probable o freqüent.<br />Operacions amb dades complexes.<br />Segments de codi amb algorismes o lògica complexa.<br />Codi que utilitzi particularitats del computador, sistema operatiu o llenguatge.<br />Les àrees de canvi probable o freqüent poden ser:<br />Dependencies del Hardware.<br />Entrada/Sortida.<br />Àrees de difícil disseny.<br />Variables d’estat.<br />Limitacions en el tamany de les dades.<br />Àrees de programació relacionades amb estructura de processos empresarials. <br />5.5 Acoblament <br />Un grau d’acoblament baix significa que dues rutines son relativament independents entre sí: La modificació d’una d’elles no afectarà a l’altre. Pel contrari un grau d’acoblament alt significa que dues rutines depenen l’una de l’altre.<br />Existeixen diferents graus d’acoblament, a continuació s’exposen els NO Problemàtics:<br />Acoblament per dades simples. L’únic intercanvi d’informació que existeix entre dues rutines és una llista de paràmetres no estructurats. Per exemple, la funció tan(angle) por cridat dins seu a sin(angle) o cos(angle).<br />Acoblament simple per objectes. Un subsistema està acoblat de forma simple a un objecte si en crea una instància. <br />Acoblament de lectura-lectura per dades globals. Es dona quan dues rutines llegeixen de les mateixes dades globals.<br />Els tipus d’acoblament perillosos són:<br />Acoblament incomplet per dades estructurades. Es dona quan una rutina utilitza només una petita part de l’objecte que instancia. Només es permissible si la rutina té previsió d’acabar usant tota la estructura.<br />Acoblament de control. Una rutina crida a una segona especificant la operació que ha de realitzar per mitjà d’un paràmetre de control.<br />Acoblament de lectura-escriptura per dades globals. Dues rutines llegeixen i escriuen les mateixes dades globals. <br />Acoblament semàntic. Un mòdul A fa ús d’informació no pública d’un mòdul B en la seva interacció amb aquest.<br />Acoblament patològic. Una rutina modifica el codi o les dades locals d’una segona.<br />UNA BONA RUTINA HA DE TENIR UN GRAU BAIX D’ACOBLAMENT.<br />5.6 Codificació<br />No existeix una relació demostrada entre la longitud d’una rutina y la seva eficiència o nombre de defectes.<br />Es recomana que una rutina no s’allargui més de 80 línies de codi.<br />No són recomanables les rutines de mes de 200 línies.<br />Si un bloc de codi o mètode necessita un comentari interior, s’ha de plantejar la possibilitat de constituir un rutina a part amb una contracció del comentari com a nom.<br />Si un bloc de codi deixa de ser útil s’eliminarà totalment i no es deixarà comentat “per si de cas”.<br />Tot mètode ha d’ésser emprat per algú.<br />5.7 Paràmetres<br />Els paràmetres d’una rutina han d’estar ordenats de la següent manera:<br />Paràmetres d’entrada o només lectura.<br />Paràmetres transport o lectura/escriptura.<br />Paràmetres exclusivament de sortida.<br />Si diverses rutines usen paràmetres similars, l’ordre en la llista de paràmetres ha de ser coherent. Per exemple, moltes de les funcions de l’API de Windows requereixen d’un Handle com a paràmetre. Aquest, sempre serà el primer de la llista.<br />Tot els paràmetres que es passen a una funció han d’ésser emprats per aquesta.<br />Els paràmetres Resultat – Estat, sempre han de ser els útims.<br />Els paràmetres mai s’utilitzaran com a variables temporals dins d’una funció.<br />A tall d’exemple, el següent fragment de codi es inadmissible:<br />int operacio (a, b){<br />a := b+1; X <br />b:= a/3;<br />a:=a+b;<br />}<br />Només s’acceptarà aquest cas per a realitzar una normalització del paràmetre d’entrada. P.e cadena := cadena.toUpperCase.<br />Un nombre màxim recomanat de paràmetres per una rutina és 7. Un nombre superior dificulta enormement la comprensió funcional de la rutina. <br />Un bon disseny per a una rutina es aquell que conté la retenció les seves pròpies fallades i les dels nivells inferiors. Això no vol dir ignorar sinó tractar i actuar en conseqüència els errors obtinguts.<br />Cap rutina es dissenyarà assumint un pas de paràmetres concret.<br />Cap rutina es programarà assumint un tipus de crida concret ( llunyana, propera, per interrupció...).<br />5.8 Valors de retorn<br />Totes les funcions que retornin qualsevol tipus d’estructura de dades, retornaran una estructura buida per indicar absència de resultats i mai NULL.<br />Sempre que retornem cadenes s’ha de documentar si són per ús humà o per a ús per part d’altres processos.<br />Mai s’utilitzarà un retorn per a consum humà per a prendre decisions de procés dins d’una rutina. Un cas particular seria emprar la funció .toString de Java sobre un objecte, per tal d’extreure informació dins d’un procés.<br />6 Mòduls (Packages i Namespaces)<br />6.1 Creació<br />Els mòduls serveixen per aïllar conjunts de classes molt relacionades entre sí i que col·laboren per tal d’aconseguir un objectiu o funcionalitat comú. Un mòdul pot ser un package en Java o un namespace en c++/.Net.<br />S’haurà de seguir una perspectiva modular i d’ocultació d’informació en qualsevol desenvolupament. Això últim vol dir que la informació ha d’estar molt cohesionada amb les funcions que la tracten, i no ser visible des de l’exterior.<br />No es podrà accedir mai a les interioritats d’una estructura abstracta, sinó que crearem funcions per a fer-ho:INCORRECTE: Client := Client.^next. { LLISTA ORDENADA }CORRECTE: Client := ObtenirSegClient(Client); <br />6.2 Nomenclatura<br />La nomenclatura dels mòduls es farà de la següent manera:<br />com.empresa.projecte.component1.component2<br />on component2 sempre serà opcional i component1 serà opcional en projectes que continguin menys de 15 classes.<br />7 Tipus de dades i variables<br />7.1 Definició de tipus de dades<br />Tot i que el llenguatge ens ho permeti, no es redefiniran tipus estandards.<br />p.e typedef integer longint;<br />S’evitarà en la mesura del possible, la declaració implícita de variables, ja que és sinònim de no declaració i dificulta la comprensió del codi.<br />S’evitarà la modificació del tipus d’una variable durant l’execució tot i que el llenguatge ho permeti.<br />7.2 Noms de variables<br />Igual que amb les rutines, el nom recomanat per a una variable no excedirà els 16 caracters. Es nombraran les variables, acord amb el seu significat i mai acord amb el seu tipus.<br />Es procuraran evitar les variables com i, a, j , n en bucles, independentment de la mida d’aquest.<br />Tret dels llenguatges amb comprovació de tipus dèbil (Pascal, C) ,en l’actualitat la Notació Húngarà ha quedat obsoleta i el seu ús queda limitat a la I capital per a la definició d’interfícies. (IClonable, ISerializable, etc.).<br />Els noms de macros començaran sempre amb (_) i les diferents paraules que els composin també aniran separades amb (_). P.e _MAX_ALUMNES<br />No s’utilitzaran noms ambigus per a la definició de variables. P.e “Col” pot significar columna o color.<br />7.3 Variables d’estat i temporals<br />Per a designar variables d’estat s’utilitzaran noms que facin referencia a l’objecte que impliquen i l’estat en concret. És a dir, utilitzarel ImpressoraActiva enlloc d’ EstatImpressora o LlumVerda enlloc de EstatLlum.<br />No es aconsellable la paraula Estat dins d’una variable ja que normalment indica el tipus de la variable però es poc descriptiu en quant a funció.<br />No s’empraran noms de l’estil tmp , tmp1, temp, per a designar variables temporals.<br />Es desaconsella l’ús de booleans com a variables d’estat. És preferible l’ús d’enumeracions amb els valors definits com a constants.<br />7.3 Variables booleanes<br />Les variables booleanes han de tenir noms que sugereixin respostes o continguts dels tipus SI/NO. P.e Exit, Correcte, Acabat<br />Els noms sempre han de ser positius. Trobat enlloc de NoTrobat.<br />No són recomanables per als casos en que una variable pot prendre dos valors però aquests no són verdader o fals. P.e Sexe, BlancNegre.<br /> Quan una variable booleana pugui prendre el valor null, no s’intentarà comprendre com funciona la combinació d’aquest valors amb els booleans. És a dir, no s’intentaran extreure regles generalistes de l’estil true or null , false or null ... sinó que tractarem cada cas de forma aïllada.<br />7.4 Arrays i cadenes<br />Es recomanable tractar els arrays com a estructures seqüencials. És a dir, estructures en les que no es pot accedir a l’element N si abans no s’ha passat per N-1 i N-2. L’accés indiscriminat a un array es similar a l’ús de “goto” dins d’un bloc de codi.<br />Aquesta recomanació té validesa sempre i quant l’array sigui homogeni en quant a les dades que conté.<br />Sempre s’evitaran, en la mesura del possible, les declaracions de mida d’array per mitjà de constants literals. Es procurarà fer ús de constants prèviament definides:<br />p.e INCORRECTE vector = new array[100];<br />CORRECTE vector = new array[_MIDA_VECTOR];<br /> 7.5 Punters<br />Tots els punters s’inicialitzaran a null sempre i quan no tinguin una assignació immediata després de la seva declaració.<br />Es convenient restringir l’ús de punters en rutines d’alt nivell.<br />No es permeten més de dues de-referències per punter:<br />p.e Llista.*Seguent.*Anterior.*Anterior = NULL ;<br />Excepte que s’estigui treballant amb objectes, s’evitaran les conversions de tipus de tipus punter.<br />7.6 Inicialització i ús<br />No es farà ús de valors amagats en les variables. Per exemple, PaginesImpreses són el nombre de pàgines que s’ha imprès i -1 si hi ha hagut algun error.<br />Quan existeixin variables globlas, s’evitarà l’accés directe per diverses rutines. P.e enlloc de fer Pagina++, totes les rutines cridaran al mètode AugmentarPagina.<br />No s’ha de fer ús de valors directes en els programes. Qualsevol nombre o cadena constant ha d’ésser substituïda per una constant amb nom. Exceptuant els següents casos: 0 , 1/ -1, 2/-2, true/false, “ “.<br />Les divisions han d’estar protegides per al cas en que el divisor sigui zero.<br />Per a tots els valors de retorn NULL, se n’ha d’especificar el seu significat.<br />No es crearan rutines que retornin null amb significats polivalents.<br />8 Estructures de control<br />8.1 Flux lineal<br />Quan un grup de sentencies s’han d’executar en un ordre concret, la dependencia de l’ordre ha de ser obvia.<br />p.e Inicialitzar()<br />InicialitzarImpressora()<br />Suposant que Inicialitzar() declara variables globals que han de ser emprades per la segona funció, es podria pensar que son rutines independents l’una de l’altre i que l’ordre no és crucial. Així doncs, la nomenclatura correcte serà:<br />InicialitzarDadesGlobals()<br />IncialitzarImpressora()<br />D’aquesta manera ja s’aprecia que les dades globals són el primer que s’han de declarar.<br />El codi ha de ser llegible de dalt a baix. Quan les crides a funció no depenguin entre si, s’agruparan a nivell de dades tractades i no a nivell d’operació.<br />Agrupant a nivell de funció, es pot trobar un codi com el següent:<br />IniDadesMensuals()<br />IniDadesSemanals()<br />IniDadesDiaries()<br />CalcDadesmensuals()CalcDadesSemanals()CalcDadesDiaries()<br />En canvi, la forma correcta amb agrupació per dades seria:<br />IniDadesMensuals()<br />IniDadesSemanals()<br />IniDadesDiaries()<br />CalcDadesmensuals()<br />CalcDadesSemanals()CalcDadesDiaries()<br />Es defineix l’obertura d’una variable com a el nombre de línies entre dues referències consecutives a la variable. P.e<br />a := 0<br />b := 0 obertura<br />c := 0<br />a:= b + c<br />S’ha de procurar mantenir una obertura baixa de cada variable en un mòdul.<br />Amb els llenguatges que permetin declarar variables en qualsevol punt del programa, sempre es faran les declaracions al punt més proper al seu primer ús.<br />Les variables sempre tindran el temps de vida més curt possible.<br />8.2 Flux condicional<br />No s’utilitzaran nivells d’aniuament superiors a 4, excepte en condicionals del tipus<br />If ...... Then<br />Else If ..... ThenElse If ..... Then<br />Else If ..... ThenElse ...... ;<br />Mai s’utilitzaran clàusules “Then” buides, usant la funcionalitat de la sentencia Else.<br />Les expressions condicionals complexes, s’han de simplificar fent ús de booleans temporals o funcions booleanes.<br />En una expressió booleana que enumeri diversos casos, els casos més freqüents sempre encapçalaran la funció:<br />Pe. IF esLletra(char) || esSignePuntuacio || esDigit Then ......<br />En els llenguatges on existeixi l’operador condicional, no s’utilitzaran operadors ?: aniuats.<br />No s’utilitzaran variables falses (ni fer malabarismes) per emprar la funció switch enlloc d’un if-else.<br />EntradaTeclat := LlegirEntradaTeclat()<br />Switch (EntradaTeclar.charAt(2))<br />Case ‘a’: copia(); break;<br />Case ‘b’: enganxa; break; ....<br />No s’utilitzarà el fall-through dins d’un switch. Si un fragment de codi es repeteix, replicarem el codi, i si és molt gran, el seu lloc es dins d’una rutina.<br />Aquest fragment de codi es inadmissible:<br />Switch (Token)<br />Case ‘Token1’: ................... ;<br />.........................;<br />Case ‘Token2’: ..............; break;<br />.....<br />Si un switch fa referència a un tipus enumerat, considerarà tots els casos d’aquest tipus.<br />No s’utilitzaran comparacions explícites amb booleans:<br />p.e Farem iF(esCorrecte) enlloc de IF(esCorrecte == true)<br />En estructures de control de tipus if-else, el cas positiu sempre anirà dins del IF.<br />8.2 Flux iteratiu<br />Es recomanable tractar l’interior d’un bucle com a rutina o caixa negra, aplicant tot el que s’ha comentat sobre acoblament i cohesió amb la resta de codi.<br />Les condicions inicials i de finalització d’un bucle han de ser clares, sense que faci falta examinar l’interior del bucle per entendre’n el funcionament.<br />Quan un bucle sigui infinit, es recomanable anunciar-ho quan abans. Així doncs farem while(true) enlloc de Do ....... while(true).<br />S’han d’evitar bucles de cos buit, exceptuant aquells casos tant trivials que es puguin llegir com a frase. P.e <br />Do while (!KeyPressed)<br />Definim l’obertura d’un bucle com al nombre de línies que ocupa. Un cop més aquesta s’ha de mantenir baixa.<br />La longitud màxima recomanada per a un bucle és de 66 línies.<br />Dins dels bucles FOR, s’ha d’evitar aquell codi que depengui d’un valor concret de l’index de control.<br />p.e for(int posicio=0; posicio < MAX_POSICIO; posicio ++){<br />if(posicio == POSICIO_ESPECIAL)<br />...........<br />}<br />No s’utilitzarà el valor d’un índex de control fora del bucle que controla.<br />No s’utilitzarà un aniuament de bucles superior a 3.<br />No s’utilitzaran bucles amb més d’una variable d’iteració<br />p.e for(int a, int b; ...........; a++, b+=2)<br />8.2 Flux recursiu<br />S’evitarà l’ús de recursivitat si existeix una solució iterativa igual de llegible.<br />La llegibilitat serà l’únic criteria a considerar exceptuant que el propi programa indiqui certs requisits de rendiment, tamany en memòria, etc-<br />Es defineix l’obertura de la recursió com al nombre de rutines que hi ha entremig fins que es tanca el bucle recursiu. Per exemple, si A crida a B, B crida a C y C crida a A, l’obertura es 2 (B i C).<br />No es recomanable una obertura superior a 2.<br />Quan es faci ús d’aquest tipus d’algorismes s’haurà de controlar que hi hagi prou memòria a la pila.<br />8.3 Complexitat<br />Definim la complexitat ciclomàtica de McCabe com el nombre possible de camins diferents en un programa ( Software Engineering Insitute, Carnegie-Mellon 2000).<br />Una forma de calcular la complexitat de McCabe d’un programa és:<br />Començar amb una complexitat 1.<br />Afegir 1 per cada if,while,do-while, for, and, or,xor,?: i cada un dels casos d’un switch.<br />La complexitat s’evaluarà de la següent manera:<br />0 – 7 . Complexitat acceptable.<br />8 –15. Seria convenient simplificar la rutina.<br />15+ . S’ha de dividir la rutina.<br />