fp_asix_m03_u4_pdfindex

72
Programació modular Joan Arnedo Moreno Programació bàsica (ASX) Programació (DAM)

description

ioc java 4

Transcript of fp_asix_m03_u4_pdfindex

  • Programaci modularJoan Arnedo Moreno

    Programaci bsica (ASX)Programaci (DAM)

  • Programaci bsica (ASX)Programaci (DAM) Programaci modular

    ndex

    Introducci 5

    Resultats daprenentatge 7

    1 Descomposici de problemes 91.1 Disseny descendent . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

    1.1.1 Exemples daplicaci de disseny descendent . . . . . . . . . . . . . . . . . . . . . . 111.1.2 Reutilitzaci de subproblemes resolts . . . . . . . . . . . . . . . . . . . . . . . . . . 151.1.3 Aplicaci correcta del disseny descendent . . . . . . . . . . . . . . . . . . . . . . . . 17

    1.2 Disseny descendent aplicat a la creaci de programes . . . . . . . . . . . . . . . . . . . . . . 171.2.1 Declaraci de mtodes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181.2.2 Canvis en el mtode principal en declarar altres mtodes . . . . . . . . . . . . . . . . 201.2.3 Accessibilitat de variables dins una classe . . . . . . . . . . . . . . . . . . . . . . . . 211.2.4 Codificaci de mtodes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221.2.5 Invocaci de mtodes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 231.2.6 Inicialitzaci diferida de variables . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25

    1.3 Un exemple ms complex . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 271.3.1 Descomposici de problema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 281.3.2 Esquelet de la classe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 311.3.3 Implementaci del tercer nivell de descomposici . . . . . . . . . . . . . . . . . . . . 321.3.4 Implementaci del segon nivell de descomposici . . . . . . . . . . . . . . . . . . . 341.3.5 Implementaci del primer nivell de descomposici . . . . . . . . . . . . . . . . . . . 351.3.6 Implementaci del problema general . . . . . . . . . . . . . . . . . . . . . . . . . . . 361.3.7 Millores sobre la soluci final . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37

    1.4 Soluci dels reptes proposats . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39

    2 Parametritzaci de mtodes 412.1 Parmetres dentrada . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41

    2.1.1 Motivaci: definici de problemes semblants . . . . . . . . . . . . . . . . . . . . . . 422.1.2 Declaraci i s de mtodes amb parmetres dentrada . . . . . . . . . . . . . . . . . . 442.1.3 Manipulaci dels parmetres dentrada . . . . . . . . . . . . . . . . . . . . . . . . . 47

    2.2 Parmetres de sortida . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 492.2.1 Motivaci: Definici de problemes que generen un resultat concret . . . . . . . . . . 492.2.2 Declaraci i s de mtodes amb un parmetre de sortida . . . . . . . . . . . . . . . . 50

    2.3 Quan declarar parmetres dentrada o sortida . . . . . . . . . . . . . . . . . . . . . . . . . . 532.3.1 Millorant la llegibilitat de codi amb parmetres . . . . . . . . . . . . . . . . . . . . . 532.3.2 El principi docultaci / encapsulaci . . . . . . . . . . . . . . . . . . . . . . . . . . 542.3.3 Exemples de mtodes parametritzats . . . . . . . . . . . . . . . . . . . . . . . . . . . 55

    2.4 Un exemple de disseny descendent amb mtodes parametritzats . . . . . . . . . . . . . . . . 582.4.1 Descomposici de problema . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 592.4.2 Implementaci del segon nivell de descomposici . . . . . . . . . . . . . . . . . . . 612.4.3 Implementaci del primer nivell de descomposici . . . . . . . . . . . . . . . . . . . 622.4.4 Implementaci del problema general . . . . . . . . . . . . . . . . . . . . . . . . . . . 66

  • Programaci bsica (ASX)Programaci (DAM) Programaci modular

    2.4.5 Implementaci final . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 672.5 Solucions als reptes proposats . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 69

  • Programaci bsica (ASX)Programaci (DAM) 5 Programaci modular

    Introducci

    Un cop coneixeu els tres tipus destructura de control (seqencial, selecci i repeti-ci), ja disposeu de totes les eines bsiques per poder implementar algorismes dinsels vostres programes dordinador, usant la tcnica de la programaci estructurada.La seva aplicaci correcta us permet generar un codi polit i ordenat, relativamentfcil dentendre per una tercera persona. Ara b, el punt realment ms importanta lhora de dur a terme un programa dordinador s la definici del seu algorisme.Si ja dentrada no dissenyeu un algoritme correcte, el programa mai funcionarcorrectament, independentment del fet que susin correctament els principis de laprogramaci modular o que el codi font no tingui errors de sintaxi.

    Per a programes senzills, el disseny dalgorismes es pot realitzar demanera ad hoc,pensant les diferents passes ordenades que cal seguir en llenguatge natural, quedesprs poden ser tradudes a instruccions del codi font. Ara b, per a programescomplexos, en els quals hi hamoltes passes interrelacionades, pot ser fcil perdres,o crear una descripci enrevessada o difcil de seguir. Hi ha tants detalls queus resultar impossible tenir-los tots presents alhora al cap. El resultat s queresulta molt ms fcil equivocar-se o, fins i tot, un cop se sap que hi ha un error enel disseny, intentar esbrinar on es troba aquest. Per tant, s til disposar dunametodologia de treball que doni un cop de m en aquest aspecte. En aquestaunitat es presentar una metodologia fora popular i til a lhora de dissenyaralgorismes complexos: el disseny descendent. En poques paraules, aquest esbasa en lestratgia, aplicable a qualsevol camp i no noms a la programaci, dedividir problemes complexos en un conjunt de problemes ms simples i fcilsdatacar i entendre.

    A lapartat Descomposici de problemes sexposen els principis del dissenydescendent aplicat dins el context de la creaci dalgorismes. Per poder dur-loa terme, es presenta un nou tipus de bloc dinstruccions que podeu usar dinsels vostres programes, els mtodes. Si b aquests ja havien estat introdutsamb anterioritat, noms shavien vist des del punt de vista de la seva invocaciper manipular cadenes de text. Aqu veureu amb una mica ms de detall comfuncionen realment, la seva utilitat i com en podeu definir de nous, inventatsper vosaltres, en els vostres programes. De moment, per, aquest apartat nomsofereix una visi general sobre com la seva existncia est vinculada a laplicacidel disseny descendent dalgorismes, sense veure tots els seus detalls.

    Els detalls ms complexos de la declaraci i s de mtodes es detalla a lapartatParametritzaci de mtodes. Aqu es presenta la seva utilitat com a mecanismeper manipular i produir dades, de manera que el seu s resulti molt ms verstil ipuguin ser invocats amb resultats similars als descrits per operar amb cadenes detext. Aix permet crear un recull deines reusables dins els vostres programes pertransformar informaci, de manera que seviti haver descriure codi repetit.

  • Programaci bsica (ASX)Programaci (DAM) 6 Programaci modular

    Heu de tenir en compte que la declaraci de mtodes i la seva invocaci s unaeina usada amb assidutat als programes de qualsevol llenguatge de programaci,per la qual cosa comprendre-la i saber quan usar-la s de capital importncia per aun programador. En el mn real, s complicat dur a terme programes complexosque no incloguin mtodes. Per tant, conv que a partir dara sempre que feu unprograma intenteu aplicar els mecanismes explicats en aquest mdul per tal dedividir el codi en diferents mtodes, i si pot ser, reaprofitar-los en diferents llocsdins el programa.

  • Programaci bsica (ASX)Programaci (DAM) 7 Programaci modular

    Resultats daprenentatge

    En finalitzar aquesta unitat, lalumne/a:

    1. Analitza els conceptes relacionats amb la programaci modular

    2. Analitza els avantatges i la necessitat de la programaci modular

    3. Aplica el concepte danlisi descendent en lelaboraci de programes

    4. Modularitza correctament els programes realitzats.

    5. Realitza correctament les crides a funcions i la seva parametritzaci.

    6. T en compte lmbit de les variables en les crides a les funcions

  • Programaci bsica (ASX)Programaci (DAM) 9 Programaci modular

    1. Descomposici de problemes

    Igual que amb la immensa majoria de tasques amb cert grau de complexitat dinsel mn real, la creaci dun programa requereix un pas previ on cal reflexionarsobre qu s exactament el que voleu fer i com assolireu la vostra fita. s molt pocrecomanable afrontar aquesta tasca ja seient directament davant de lordinador,obrint lentorn de treball i comenant a escriure lnies de codi. Aquesta opcinoms s realment factible quan disposeu duna certa experincia programant itrobeu que el problema que heu de resoldre, o b ja lheu tractat amb anterioritat,o sassembla molt a un altre que ja heu resolt. Per quan us enfronteu amb unproblema nou s imprescindible una etapa en la qual estudiar el problema, lesdades que voleu tractar exactament i les tasques que ha de dur a terme lordinadorper fer-ho (o sigui, lalgorisme del programa).

    Malauradament, la capacitat dels humans per copsar problemes complexos slimitada, ja que, en general, noms som capaos de mantenir una visi simultniaduns pocs elements. A aquest fet cal afegir que la presa duna decisi sobrequina passa cal dur a terme dins la descripci dun procs sempre t implicacionssobre futures passes. Per tant, quan el procs que cal realitzar s llarg o es basaen la manipulaci de molts elements diferents, s molt fcil, no ja simplementequivocar-se, sin tan sols saber per on comenar.

    Com diu la frase que satribueix aFilip II de Macednia: "Divide etimpera" (divideix i vencers). Font:Tilemahos Efthimiadis

    Un cop arribats a aquest punt, es fa evident que resultaria til disposar dalgunaestratgia que permeti fer front a la resoluci de problemes amb diferents grausde complexitat. Una de les ms populars en tots els camps, i que de ben seguruseu sovint en el vostre dia a dia, potser sense adonar-vos, s considerar que unproblema complex en realitat no sms que lagregaci dun conjunt de problemesms simples, cadascun dells ms fcils de resoldre. Per tant, si sou capaosdentendre i resoldre tot aquest conjunt de problemes simples, tamb podreu sercapaos de resoldre el problema complex.

    En conseqncia, i partint daquesta premissa, el primer pas per poder dur a termeuna tasca complexa ser trobar com descompondre-la en daltres ms simples, quellavors saniran resolent un per un.

    1.1 Disseny descendent

    Hi ha dues estratgies bsiques per resoldre la descomposici dun problema:el disseny descendent i lascendent. Aquest apartat se centra en la primera, enser la ms utilitzada per norma general, i la ms fcil daplicar a lhora de crearprogrames del nivell que abasten aquests materials.

    En el context de laprogramaci, el dissenyascendent normalmentsaplica dins el camp delorientaci a objectes.

  • Programaci bsica (ASX)Programaci (DAM) 10 Programaci modular

    El disseny descendent (top-down, en angls) s la tcnica que es basaen partir dun problema general i dividir-lo en problemes ms simples,denominats subproblemes. Dentre tots aquests, els considerats encaramassa complexos es tornen a dividir en nous subproblemes. Sanomenadescendent perqu partint del problema gran es passa a problemes ms petitsals quals donar soluci individualment.

    Lesquema daplicaci daquesta estratgia es mostra a la figura 1.1, en la qual esveu la ra del nom descendent, i saprecia com, partint de la definici del problemageneral, extreta de tasca final que voleu assolir, es crea una estructura jerrquica desubproblemes en diferents nivells. El nombre de nivells a qu cal arribar dependrde la complexitat del problema general. Per a problemes no massa complexos, hihaur prou amb un o dos nivells, per per resoldre problemes molt complexospot caldre un gran nombre de successives descomposicions. Tamb val la penaremarcar que, tot i que s recomanable que la complexitat dels subproblemes dunmateix nivell sigui aproximadament equivalent, nhi pot haver que quedin resoltscompletament en menys nivells que en daltres.

    Figura 1.1. Esquema daplicaci de disseny descendent, dacord als nivells dedescomposici del problema

    Un punt important a tenir en compte en aplicar aquesta descomposici s quecadascun dels subproblemes no es genera arbitrriament, sin que es planteja comun objectiu parcial, amb entitat prpia, per resoldre el seu problema de nivellsuperior. Un cop assolits tots aquests objectius parcials, es considera resolt eltotal.

    Els objectius finals daplicar aquesta estratgia sn:

    Establir una relaci senzilla entre problemes plantejats i el conjunt detasques a fer per resoldrels.

    Establir ms fcilment les passes per resoldre un problema.

    Fer ms fcil dentendre aquestes passes.

    Limitar els efectes de la interdependncia que un conjunt de passes t sobreun altre conjunt.

  • Programaci bsica (ASX)Programaci (DAM) 11 Programaci modular

    1.1.1 Exemples daplicaci de disseny descendent

    Com sempre, la millor manera de veure laplicaci de disseny descendent smitjanant exemples. Per comenar, aquests se centraran en la resoluci deproblemes dmbit general, que permetin veure amb claredat el procs sigui quinsigui el context, abans dentrar en el cas concret de la generaci dun programa.

    Una unitat formativa

    Un cas fora directe daplicaci de disseny descendent s lescriptura dundocument de certa complexitat, com per exemple, un llibre o una unitat formativade lIOC. Es tracta dun cas directe ja que lestructura dun document daquesttipus s evidentment jerrquica, basada en captols, seccions, subseccions, etc.Aix, doncs, tot just davant vostre ara mateix teniu el resultat directe daplicardisseny descendent sobre un problema.

    Figura 1.2. Descomposici duna Unitat Formativa seguint el disseny descendent

    En un cas com aquest, quan es planteja que cal fer una unitat formativa, tot i que esparteix ja dunes directrius o idea general dall que es vol explicar (per exemple,uns objectius daprenentatge), estareu dacord que no seria gaire assenyat seureja immediatament davant dun processador de text i posar-se a escriure, atacantfrontalment el problema. Aquesta aproximaci normalment porta a no saber benb per on comenar, o simplement posar fi a un text incomprensible, amb fins itot explicacions repetides. s ms eficient comenar amb una etapa de dissenyen la qual sestableixi un primer nivell dobjectius parcials en la redacci: unadivisi inicial en apartats. Aquest primer nivell de descomposici de ben segur

  • Programaci bsica (ASX)Programaci (DAM) 12 Programaci modular

    que encara ser massa genric, per ja ha dividit el problema inicial en daltresms petits.

    Un cop arribats a aquest punt, per cada apartat, es van fent successives divisionsen seccions, subseccions, etc. partint de conceptes ms generals que es volenexplicar cap a conceptes ms especfics. Un cop es considera que sha arribat aun concepte prou especfic com per poder ser explicat de manera autocontingudai de manera relativament fcil dentendre pel lector, ja no cal descompondre ms.Evidentment, un cop tractats tots els apartats, s possible trobar-se que algunsapartats o seccions estan dividits en ms subapartats que daltres. Aix no sproblema. Ara b, el que s que ha de ser cert sempre s que cada subapartat escorrespongui a una temtica concreta, amb una entitat i sentit propi (dacord al seuttol), i mai es tracta dun calaix de sastre on sexpliquen moltes coses diferentspoc relacionades entre elles. Per exemple, la figura 1.2 mostra la descomposiciduna unitat dacord a aquests criteris.

    Com es pot veure, en aquest cas, el resultat daplicar la descomposici us dna coma resultat lndex de la unitat. Estareu dacord que s molt ms senzill editar undocument partint dun ndex preestablert, amb noms de seccions autoexplicatiussobre all que han de tractar, que no pas actuant de manera improvisada. Addici-onalment, aquest procs de descomposici assoleix una altra fita molt importantque va ms enll de facilitar letapa de redacci del text. El document resultanttamb resulta molt ms fcil de seguir i entendre per part dels futurs lectors.

    Una recepta de cuina

    Si b lexemple del document de text s prcticament dels ms directes que hi haper illustrar com la divisi dun problema en daltres ms petits s de gran ajut,hi ha un petit detall a tenir en compte. La majoria de documents de text, i s elcas de les unitats formatives, no descriuen pas algorismes, que s al cap i a la fiel que haureu de fer en un programa. Ara b, hi ha prou que el text descrigui unaseqncia de passes per dur a terme una fita perqu ja es converteixi en algorisme.Per exemple, unmanual dinstruccions permuntar unmoble o una recepta de cuina.En aquests casos, per fer la redacci, el procs general es divideix igualment enapartats i seccions que es corresponen a tasques individuals i concretes dins delprocs general.

    Una recepta de cuina s unalgorisme, i es pot descompondreusant disseny descendent (Font:

    jetalone)

    Per tant, el que es proposa fer, a mode dexemple, s dur a terme un procsde descomposici en subproblemes duna recepta de cuina de fideus japonesosyakisoba () sense carn. En un cas com aquest, el concepte de problemacomplex s relatiu, ja que tot depn de les habilitats i coneixements culinaris dellector. Per no simplificar massa lexemple, se suposar que alguns aspectes comfregir o saltar no es consideren tasques simples, i cal tenir ben present el procs depreparaci. La figura 1.3 mostra una proposta desquema de descomposici usantdisseny descendent. El format emprat per establir el nivell de descomposici s elmateix que en lexemple anterior. Estudieu-la atentament i dediqueu uns momentsa reflexionar si vosaltres ho haureu fet duna altra manera.

  • Programaci bsica (ASX)Programaci (DAM) 13 Programaci modular

    Figura 1.3. Descomposici de la preparaci duna recepta de cuina

    Ats que aquest exemple s que est expressant la descomposici dun procs, hi haalguns aspectes a tenir en compte. Duna banda, noteu com la nomenclatura usadaper identificar cada subproblema indica clarament qu es vol assolir, de maneraque tant vosaltres com un tercer observador pot tenir una idea clara dall que calresoldre per dur a terme la tasca final. Aix s molt important. Ara b, daltrabanda, si b amb aquest identificador se sap qu cal resoldre, no se sap comes resol cada subproblema. En aquest sentit, es considera que un subproblema suna abstracci sobre part del procs complet. Definir lalgorisme que resol cadasubproblema individual ser ja letapa segent.

    Per exemple, un cop es t clara la descomposici, ja es podria decidir cercarlalgorisme per resoldre el subproblema Preparar oli per fregir, que podria ser:

    1. Agafar ampolla doli de gira-sol.

    2. Omplir paella fins a un ter.

    3. Posar foc al mxim.

    4. Mentre loli no sescalfi.

    5. Esperar.

    Noteu com, per resoldre aquest punt, no s necessari saber absolutament resde la resta del procs general. Aix indica que cada subproblema del nivellms baix planteja un seguit de tasques totalment autocontigudes. Aquest procs

  • Programaci bsica (ASX)Programaci (DAM) 14 Programaci modular

    llavors saniria repetint per cada subproblema, normalment comenant resolentels problemes ms senzills (nivells inferiors), i anant a poc a poc resolent els mscomplexos (nivells superiors), fins a arribar al problema general, que s el de nivellms alt.

    Aquest ordre recomanat es deu al fet que, durant aquest procs, per resoldresubproblemes de nivells superiors, s possible referir-se a subproblemes de nivellsinferiors. La millor manera de veure aix s veient com es resoldria, per exemple,el subproblema Fregir pastanagues:

    1. Preparar oli per fregir.

    2. Agafar els bocins de pastanaga.

    3. Rossejar pastanagues.

    4. Treure-les de la paella.

    5. Desar en un plat.

    6. Netejar la paella.

    Noteu com, per resoldre aquest subproblema, en els punts 1, 3 i 6 precisamentsest referint a subproblemes de nivell inferior, que es consideren resolts si seguimlordre de resoluci descrit. Tamb noteu com, per resoldre un subproblema, tantes poden usar subproblemes ja resolts de nivell inferior com passes addicionals quees considerin prou simples. Per tant, des del punt de vista dordre de les passesque sestan seguint, el procs seguiria a grans trets el flux de control de la figura1.4.

    Figura 1.4. Flux de control de lalgorisme basat en disseny descendent per fregir unes pastanagues

    En aquesta figura, el punt ms important s veure com cada subproblema esconsidera una entitat estrictament independent i autocontinguda dins de tot el

  • Programaci bsica (ASX)Programaci (DAM) 15 Programaci modular

    procs, a la qual shi accedeix des dun altre de nivell superior. Quan es fa, lesseves passes sn seguides dinici a fi, i en acabar es continua exactament per onus haveu quedat en el nivell superior.

    1.1.2 Reutilitzaci de subproblemes resolts

    Els exemples de la unitat formativa o la recepta de cuina, a simple vista, aparentenseguir un esquema molt similar. Els diferents nivells segueixen una ordenaciseqencial (1, 1.1, 1.1.1 ... 2, 2.1, etc.), de manera que, fet i fet, els subproblemeses van resolent de manera ordenada i un cop resolt el darrer subproblema, la tascageneral est prcticament finalitzada. Aix encaixa amb el model estrictamentjerrquic del problema general descompost tal com sha exposat inicialment.

    Reaprofitant subproblemes resolts usestalvieu reinventar la roda. Font:Derek Ramsey

    Ara b, la descomposici mitjanant disseny descendent permet fer s dunacaracterstica molt til quan susa per dissenyar algorismes. Es tracta de lapossibilitat de cercar subproblemes idntics, o si ms no fora semblants, ireaprofitar la seva soluci en ms dun lloc dins del problema general. Un copshan resolt una vegada, no tindria sentit tornar-los a resoldre de nou repetidesvegades. Sobre aquesta circumstncia, de moment sestudiar noms el cas desubproblemes exactament iguals.

    Per exemple, si us fixeu en la descomposici de la recepta de cuina, podeu observarque hi ha subproblemes repetits. Es tracta de Preparar paella per fregir i Netejarpaella. No noms shan descrit ja dentrada amb noms idntics, sin que, sius pareu a pensar, les passes que engloben tamb ho seran. Els elements quees manipulen per a la seva resoluci (paella i oli) i la manera com es fa aquestamanipulaci sn exactament els mateixos. Per tant, un cop shan definit les passesper resoldrel la primera vegada, ja no cal tornar-ho a fer.

    Aneu amb compte, ja que per considerar que dues solucions sn idntiques, elselements que intervenen han de ser exactament els mateixos. Aix, doncs, Tallarcebes i Tallar pastanagues sn certament subproblemes molt semblants, perno realment idntics, ja que es manipulen elements diferents.

    Un cop detectada aquesta caracterstica del disseny descendent, s el moment dematisar la descripci de descomposici en nivells de la figura 1.1. En realitat,el procs s ms aviat semblant al que descriu la figura 1.5, la qual indica uncanvi de plantejament, ja que qualsevol subproblema dun nivell donat pot serpart de qualsevol subproblema dun nivell superior. Per remarcar aquest fet, a lafigura cada subproblema no senumera usant un ndex associat al subproblema denivell superior on pertany, sin directament dacord al nivell on pertany. No hi haexclusivitat dins la jerarquia.

  • Programaci bsica (ASX)Programaci (DAM) 16 Programaci modular

    Figura 1.5. Esquema daplicaci de disseny descendent amb subproblemes repetits

    Aquesta circumstncia tamb fa que, a lhora de considerar el flux de control delalgorisme, aquest adopti una forma especial. Per resoldre dues tasques diferentses comparteix un mateix conjunt de passes, tal com mostra la figura 1.6, per alcas tot just esmentat. Aquest fet s important que el tingueu ben present, ja que tconseqncies molt directes a lhora dimplementar un algorisme quan es tractadun programa dordinador.

    Figura 1.6. Flux de control de lalgorisme basat en disseny descendent per fregir pastanagues o cebes

    En conclusi, en descompondre un problema, s especialment encertatintentar fer-ho de manera que es forci laparici de subproblemes repetits,i aix la seva resoluci es pot reaprofitar en diversos llocs.

  • Programaci bsica (ASX)Programaci (DAM) 17 Programaci modular

    1.1.3 Aplicaci correcta del disseny descendent

    Un aspecte que heu de tenir en compte en aplicar disseny descendent s que estracta duna estratgia basada en unes directrius generals per atacar problemescomplexos, per no s cap esquema determinista que us garanteixi que sempreobtindreu la millor soluci. Aix vol dir que, partint dun mateix problema,diferents persones poden arribar a conclusions diferents sobre com dur a terme ladescomposici. Dentre totes les solucions diferents possibles, algunes es podenconsiderar millors que daltres. De fet, res impedeix, a partir ja una soluciconcreta, aplicar refinaments que la millorin. Per tant, s interessant poder avaluarsi la descomposici que heu fet va per bon cam o no.

    Alguns dels criteris en que us podeu basar per fer aquesta avaluaci sn elssegents:

    Si un problema que sembla a priori fora complex es descompon en moltspocs nivells, potser val la pena fer una segona ullada. Inversament, si unproblema no massa complex t massa nivells, potser sha anat massa llunyen la descomposici.

    Veure si el nombre de passes incloses a cadascun dels subproblemes no sexcessivament gran i s fcil de seguir i entendre. En cas contrari, potserencara faria falta aplicar nous nivells de descomposici.

    Repassar que els noms assignats als subproblemes siguin autoexplicatius iexpressin clarament la tasca que estan resolent. Sense ni tan sols llegir lesseves passes, caldria entendre perfectament qu sassoleix en resoldrels. Encas contrari, potser la descomposici no est agrupant conjunts de passesrealment relacionades entre elles.

    Si absolutament cap dels subproblemes s reutilitzat enlloc, especialmenten descomposicions en molts nivells, s molt possible que no shagi triatcorrectament la manera de descompondre alguns subproblemes.

    Vinculat al punt anterior, laparici de subproblemes molt semblants oidntics, per tractats per separat en diferents llocs, tamb sol ser indici queno sest aplicant la capacitat de reutilitzar subproblemes correctament.

    1.2 Disseny descendent aplicat a la creaci de programes

    Un cop disposeu dun marc de referncia general sobre com aplicar dissenydescendent, s el moment daplicar la mateixa tcnica per a la creaci dunprograma. Per comenar, es mostra laplicaci de disseny descendent sobre unprograma de complexitat baixa i que ja coneixeu, de manera que el resultat de ladescomposici sigui molt simple. Aquest serveix com a fil argumental per poderanalitzar alguns dels aspectes importants del disseny descendent i veure com s

  • Programaci bsica (ASX)Programaci (DAM) 18 Programaci modular

    No totes lesdescomposicions han detenir sempre molts nivells.Si el programa s simple,

    nhi haur pocs.

    possible implementar la descomposici en subproblemes resultants, dacord a lasintaxi del llenguatge Java.

    El problema del que es parteix s, o hauria de ser, un conegut vostre: un programaque, a partir duna llista de 10 valors enters, els mostri per pantalla ordenats.

    Abans de comenar, s una bona idea pensar quina mena de dades cal manipulari com semmagatzemaran, ja que aix us permetr avaluar en cada pas de ladescomposici si un problema s massa complex encara o no. En aquest cas calmanipular una llista denters, per la qual cosa el ms assenyat seria emmagatzemar-la en forma dun array.

    Com sha vist per al cas general daplicaci de disseny descendent, una bonamanera de descompondre el problema en subproblems s establir quines snles parts diferenciades, o etapes, que el composen. Cada etapa es correspondra un subproblema que cal resoldre. El ms important en aquest pas s quecada subproblema correspongui sempre a una tasca concreta amb un objectiu aresoldre clarament diferenciat. Ha de ser fcil assignar-li un nom. En cas contrari,segurament no sest fent b la descomposici.

    Per a aquest programa, es pot considerar que el divideix en tres parts, o subproble-mes, a resoldre:

    llegir la llista denters,

    ordenar-la, i

    mostrar-la per pantalla.

    Un cop arribats a aquest primer nivell de descomposici, s el moment deplantejar-se si cada subproblema s massa complex o no. En aquest cas, sesuposa que ja domineu el conjunt dinstruccions que calen, com llegir una llistadenters de longitud coneguda (desant-los en un array), com ordenar un array(usant lalgorisme de la bombolla) i com mostrar-lo per pantalla (mitjanant unrecorregut). Per tant, es pot considerar que tots els subproblemes plantejats nosn excessivament complexos i el procs de descomposici acaba.

    1.2.1 Declaraci de mtodes

    Un cop descompost el problema general, s el moment de crear el programaque el resol mitjanant codi font. Per aix, caldr decidir, per a cadascun delssubproblemes que shan detectat, quines instruccions cal executar per resoldrelindividualment. Els llenguatges de programaci permeten una implementacidirecta daquest procs, en oferir mecanismes per agrupar o catalogar blocsdinstruccions i etiquetar-los amb un identificador, dacord al seu subproblemaassociat.

  • Programaci bsica (ASX)Programaci (DAM) 19 Programaci modular

    En general dins dels llenguatges de programaci, sanomena una funci aun conjunt dinstruccions amb un objectiu com que es declaren de maneraexplcitament diferenciada dins del codi font mitjanant una etiqueta oidentificador.

    Per tant, per cada subproblema a resoldre, dins del vostre codi font shaur dedefinir una funci diferent. En el llenguatge Java, aquests conjunts dinstruccionssels anomena mtodes, en lloc de funcions, per a efectes prctics, els podeuconsiderar el mateix. Aquest terme no s nou, ja que ha estat usat amb anterioritatsota dos contextos diferents, si b mai shavia entrat en molt de detall en la sevadescripci ni shavia justificat el seu format.

    Quan es parla de mtode principal, es tracta dun conjunt dinstruccionsque, etiquetades sota un identificador anomenat main, resolen el problemageneral (o sigui, tot el programa). Ats que fins al moment no shavia aplicatdisseny descendent, no hi havia subproblemes, i per tant en el vostre codifont noms hi havia definit aquest nic mtode. No en calia cap altre.

    Quan es parla de la invocaci dun mtode sobre valors de certs tipus dedades complexos, com les cadenes de text (String), es tracta dexecutar unconjunt dinstruccions amb un objectiu com: transformar la cadena de texto obtenir dades contingudes.

    Com podeu veure, tot i no haver entrat en detall, la manera com shan usat fins almoment els mtodes s coherent amb la definici que tot just sha presentat. Apartir dara comenareu a estudiar-los amb ms profunditat.

    La declaraci bsica dun mtode es fa usant la sintaxi que es mostra tot seguit.Com podeu veure, el seu format s molt semblant a com es declara el mtodeprincipal (per no exactament igual, alerta!):

    1 public void nomMetode() {2 //Aqu dins aniran les seves instruccions3 //...4 }

    Aquesta declaraci es pot dur a terme en qualsevol lloc del fitxer de codi font,sempre que sigui entre les claus que identifiquen linici i fi de fitxer (publicclass NomClasse { ... }) i fora del bloc dinstruccions mtode principal, oqualsevol altre mtode. Normalment, se sol fer immediatament a continuaci delmtode principal. La declaraci ha de seguir exactament aquest format. Lnicapart que podeu modificar s nomMetode, que no s ms que un identificador, comel duna variable, i per tant podeu triar el que vulgueu. Tot i aix, sempre haureude procurar usar algun text que sigui autoexplicatiu.

    Dacord a la descomposici proposada, dins el codi font del programa dordenacihi haur declarats tres mtodes, un associat a cada subproblema. Aquests podrienser:

    En algunes parts de laliteratura, a les funcions quecompleixen certespropietats se les anomenaaccions.

    Els identificadors delsmtodes segueixen lesmateixes convencions decodi que les variables(lowerCamelCase).

  • Programaci bsica (ASX)Programaci (DAM) 20 Programaci modular

    Per diferenciar els mtodesque resolen subproblemes

    del mtode principal, i evitarconfusions, podeureferir-vos-hi com amtodes auxiliars.

    1 public class OrdenarDescendent {2 public static void main(String[] args) {3 //Instruccions del mtode principal (problema general)4 //...5 }6 //Mtode que resol el subproblema de llegir la llista.7 public void llegirLlista() {8 //Instruccions del mtode9 //...

    10 }11 //Mtode que resol el subproblema dordenar la llista.12 public void ordenarLlista() {13 //Instruccions del mtode14 //...15 }16 //Mtode que resol el subproblema de mostrar la llista per pantalla.17 public void mostrarLlista() {18 //Instruccions del mtode19 //...20 }21 }

    1.2.2 Canvis en el mtode principal en declarar altres mtodes

    Abans de continuar, cal presentar un canvi necessari en el format dels vostresprogrames quan es vol declarar altres mtodes, associats a subproblemes, a partdel mtode principal.

    Concretament, per les caracterstiques del llenguatge Java, cal que el mtodeprincipal tingui un format molt concret. En cas contrari, hi haur un error decompilaci en futures passes del procs. Tot el codi que aniria normalment dinsel bloc dinstruccions del mtode principal subica en un nou mtode auxiliar, idins el mtode principal simplement sinvoca aquest nou mtode. De fet, no simprescindible que conegueu els detalls dels motius pels quals s necessari feraquest canvi. Simplement podeu usar el codi segent dexemple com a plantillaper generar els vostres programes, tenint en compte que tot el codi que posareunormalment al mtode principal, ara anir al mtode inici.

    1 public class OrdenarDescendent {2 public static void main (String[] args) {3 //Aqu cal usar el nom de la classe que esteu creant.4 OrdenarDescendent programa = new OrdenarDescendent();5 programa.inici();6 }7 public void inici() {8 //Instruccions del mtode principal (problema general)9 //...

    10 }11 //Resta de mtodes12 //...13 }

    En usar aquest codi com a plantilla, noteu que a la lnia segent caldria posar elnom de la classe que esteu editant, en lloc de OrdenarDescendent:

    1 OrdenarDescendent programa = new OrdenarDescendent();

  • Programaci bsica (ASX)Programaci (DAM) 21 Programaci modular

    1.2.3 Accessibilitat de variables dins una classe

    En el moment que saplica disseny descendent i les parts del codi dun programaes descomponen amb mtodes, apareix un problema. Els diferents mtodes quedefiniu serveixen per processar una informaci comuna a tots tres, en aquest cas,la llista denters, en forma darray. Aix vol dir que us caldr manipular aquestavariable en els diferents mtodes, de manera que els seus valors siguin compartitsi accessibles per tots ells. Ara b, abans de comenar, caldr decidir exactamenta on es declarar.

    Per prendre correctament aquesta decisi cal fer memria i recordar el conceptedmbit duna variable: donada una variable, noms es considerar declarada desde la lnia on sha fet fins a trobar la clau tancada segent (}). Si us hi fixeu, laconseqncia directa daix s que, ats que cada mtode pren la forma dun blocdinstruccions tancat entre claus ({ ... }), si una variable es declara dins dalgunmtode, sigui quin sigui, aquesta no es consider declarada en cap dels altres.

    Hi ha diferents maneres de solucionar aquest problema. De moment en veureu lams simple. Qualsevol dada que hagi de ser accedida en ms dun subproblemaper tal de resoldrel, caldr declarar-la com una variable global.

    Una variable global s una variable que pot ser accedida des de qualsevolinstrucci dins un mateix fitxer de codi font. El seu mbit s tot el fitxer.

    En contraposici a les variables globals, hi ha les variables locals, que sn les queheu usat fins ara: variables amb un mbit local en un bloc concret de codi.

    En Java, la sintaxi per declarar una variable global s molt semblant a la que shavist fins ara, noms varia el fet que cal afegir la paraula clau private abans de ladeclaraci i el lloc on declarar-la. Aquest darrer punt s, de fet, el ms importantsi voleu que una variable es consideri global.

    1 private tipus nomVariable = valorInicial;

    En aquest cas, la declaraci sha de fer fora de tots els mtodes, per dins del blocde claus que delimita la classe, exactament igual que quan declareu constants. Perexemple, si es vol declarar un array denters anomenat llistaEnters, es podria fer:

    1 public class OrdenarDescendent {2 //Variable global3 private int[] llistaEnters = new int[10];4 public static void main (String[] args) {5 OrdenarDescendent programa = new OrdenarDescendent();6 programa.inici();7 }8 public void inici() {9 //Instruccions del mtode principal (problema general)

    10 //...11 }12 //Mtode amb les instruccions per llegir la llista.13 public void llegirLlista() {14 }15 //Mtode amb les instruccions per ordenar la llista.16 public void ordenarLlista() {

  • Programaci bsica (ASX)Programaci (DAM) 22 Programaci modular

    17 }18 //Mtode amb les instruccions per mostrar la llista per pantalla.19 public void mostrarLlista() {20 }21 }

    En ser global, la variable llistaEnters ser accessible des de qualsevol instruc-ci dins del codi. Val la pena remarcar que en Java no s imprescindible declarar-laa linici del codi font per poder ser usada lliurement. Per exemple, si es declarsa la darrera lnia, tot just desprs de la declaraci del mtode mostrarLlista, escontinuaria considerant declarada per a tot el fitxer. Aix s una lleugera difernciarespecte a les variables locals, que noms tenen vigncia a partir de la lnia de codion shan declarat. De totes maneres, per convenci, se solen declarar al principide tot, de manera que el codi queda ordenat: primer variables globals i constants,i desprs mtodes.

    Abans de continuar, s important remarcar que ls de variables globals noms esconsidera polit en casos com aquest, on hi ha una dada que ha de ser manipuladaen diferents subproblemes. Per a altres dades ds limitat a un nic mtode(comptadors o semfors de bucles, resultats temporals doperacions, etc.), caldrdeclarar-les en el bloc de codi corresponent i mai com una variable global.

    1.2.4 Codificaci de mtodes

    Un cop ja es disposa del mtode principal adaptat, les dades generals del programadeclarades com variables globals i la declaraci dun mtode associat a cadasuproblema resultant la descomposici del problema general, ja podeu procedira escriure les instruccions de cada mtode. En aquest aspecte, les claus quedelimiten un mtode (public void nomMetode() { ... }) conformen elbloc dinstruccions que resol aquell problema concret.

    Lordre en el qual caldr resoldrel s per nivells de descomposici, normalmentcomenant pel nivell ms baix, ja que s el ms intutiu. Per les caracterstiquesde la descomposici mitjanant disseny descendent, si lheu aplicat correctament,la resoluci de cada mtode hauria de ser una tasca totalment autocontinguda iindependent. Per tant, haureu de poder resoldre en qualsevol ordre els mtodesassociats a problemes dun mateix nivell de descomposici. Si apareix algunadependncia, s que la descomposici no s correcta.

    En el cas de lexemple, noms hi ha dos nivells, el problema general i el primernivell de descomposici. En el nivell ms baix, el mtode llegirLlista tindrles instruccions que llegeixen 10 enters des del teclat i els desen a larray, elmtode ordenarLlista, les que ordenen larray i el mtode mostrarLlista, lesque el mostren per pantalla. Per tant, el codi podria ser:

    1 import java.util.Scanner;2 public class OrdenarDescendent {3 int[] llistaEnters = new int[10];4 public static void main (String[] args) {5 OrdenarDescendent programa = new OrdenarDescendent();6 programa.inici();

  • Programaci bsica (ASX)Programaci (DAM) 23 Programaci modular

    7 }8 public void inici() {9 //Instruccions del mtode principal (problema general)

    10 //...11 }12 //Mtode amb les instruccions per llegir la llista.13 public void llegirLlista() {14 System.out.println("Escriu 10 valors enters i prem retorn.");15 Scanner lector = new Scanner(System.in);16 int index = 0;17 while (index < llistaEnters.length) {18 if (lector.hasNextInt()) {19 llistaEnters[index] = lector.nextInt();20 index++;21 } else {22 lector.next();23 }24 }25 lector.nextLine();26 }27 //Mtode amb les instruccions per ordenar la llista.28 public void ordenarLlista() {29 for (int i = 0; i < llistaEnters.length 1; i++) {30 for(int j = i + 1; j < llistaEnters.length; j++) {31 //La posici tractada t un valor ms alt que el de la cerca... Els

    intercanviem.32 if (llistaEnters[i] > llistaEnters[j]) {33 //Per intercanviar valors cal una variable auxiliar34 int canvi = llistaEnters[i];35 llistaEnters[i] = llistaEnters[j];36 llistaEnters[j] = canvi;37 }38 }39 }40 }41 //Mtode amb les instruccions per mostrar la llista per pantalla.42 public void mostrarLlista() {43 System.out.print("Larray ordenat s: [ ");44 for (int i = 0; i < llistaEnters.length;i++) {45 System.out.print(llistaEnters[i] + " ");46 }47 System.out.println("]");48 }49 }

    1.2.5 Invocaci de mtodes

    Un cop resolts tots el mtodes dun nivell donat, es pot procedir a resoldre elsdel nivell superior. Ara b, en fer-ho, recordeu que teniu la possibilitat dusar lasoluci de qualsevol subproblema de nivell inferior. Per exemple, aquest era el casdaprofitar saber preparar loli a la paella per solucionar com fregir les pastanaguesa la recepta de cuina.

    Dins del codi font, aix es fa invocant algun dels mtodes que heu codificat. Perfer-ho, noms cal posar una instrucci que cont el nom del mtode a invocar, dosparntesis i el punt i coma de final de sentncia. O sigui:

    1 nomMetode();

    A efectes prctics, cada cop que sinvoca un mtode, el programa executa lesinstruccions que hi ha codificades dins aquell mtode, des de la primera fins a

  • Programaci bsica (ASX)Programaci (DAM) 24 Programaci modular

    la darrera. Quan acaba dexecutar la darrera instrucci del mtode, llavors elprograma procedeix a executar la lnia immediatament posterior a la invocacial mtode.

    Si torneu a lexemple, ara ja noms us quedaria completar el codi associat alproblema general (mtode inici). Per fer-ho, s possible invocar a llegirLLista,ordenarLlista i mostrarLlista. Donat aquest fet, el programa final ja seria elsegent. Compileu-lo i executeu-lo per veure que s aix.

    1 import java.util.Scanner;2 public class OrdenarDescendent {3 int[] llistaEnters = new int[10];4 public static void main (String[] args) {5 OrdenarDescendent programa = new OrdenarDescendent();6 programa.inici();7 }8 public void inici() {9 llegirLlista();

    10 ordenarLlista();11 mostrarLlista();12 }13 //Mtode amb les instruccions per llegir la llista.14 public void llegirLlista() {15 System.out.println("Escriu 10 valors enters i prem retorn.");16 Scanner lector = new Scanner(System.in);17 int index = 0;18 while (index < llistaEnters.length) {19 if (lector.hasNextInt()) {20 llistaEnters[index] = lector.nextInt();21 index++;22 } else {23 lector.next();24 }25 }26 lector.nextLine();27 }28 //Mtode amb les instruccions per ordenar la llista.29 public void ordenarLlista() {30 for (int i = 0; i < llistaEnters.length 1; i++) {31 for(int j = i + 1; j < llistaEnters.length; j++) {32 //La posici tractada t un valor ms alt que el de la cerca... Els

    intercanviem.33 if (llistaEnters[i] > llistaEnters[j]) {34 //Per intercanviar valors cal una variable auxiliar35 int canvi = llistaEnters[i];36 llistaEnters[i] = llistaEnters[j];37 llistaEnters[j] = canvi;38 }39 }40 }41 }42 //Mtode amb les instruccions per mostrar la llista per pantalla.43 public void mostrarLlista() {44 System.out.print("Larray ordenat s: [ ");45 for (int i = 0; i < llistaEnters.length;i++) {46 System.out.print(llistaEnters[i] + " ");47 }48 System.out.println("]");49 }50 }

    Un cop ja disposeu de tot el marc de referncia sobre com queda distribut unprograma generat per la descomposici del problema usant disseny descendent, sinteressant veure tamb quin s el flux de control de les instruccions quan aquestexecuta la invocaci a un mtode. Aix es mostra a la figura 1.7 per al cas de lainvocaci al mtode llegirLlista.

  • Programaci bsica (ASX)Programaci (DAM) 25 Programaci modular

    Repte 1: Modifiqueu el programa dexemple de manera que faci el segent.Desprs demostrar la llista ordenada, en una nova lnia, ha de dir quants dels valorssn inferiors a la meitat del valor ms gran emmagatzemat. Apliqueu dissenydescendent per afegir aquesta nova tasca, declarant i invocant els nous mtodesque faci falta.

    Figura 1.7. Flux de control de les instruccions quan sinvoca el mtode llegirLlista.

    1.2.6 Inicialitzaci diferida de variables

    La necessitat de declarar variables globals comporta una problemtica en unscasos molt especfics. Fins ara, en el moment de declarar una variable, imme-diatament li heu assignat un valor inicial. Aquest valor podia ser tant el resultatdassignar directament un literal, com una expressi o una entrada de dades perpart de lusuari. Ara b, en declarar una variable com a global, noms potser inicialitzada directament mitjanant un literal o expressions on susen altresvariables globals. No hi ha la possibilitat de fer-ho mitjanant un valor quedepengui duna entrada, per teclat o dels arguments del mtode principal. Aixsignifica que la declaraci de la variable i lassignaci del valor que es vol tractarrealment no es pot fer a la mateixa instrucci. Tot i aix, sempre que es declarauna variable cal assignar-li un valor inicial.

    Per al cas de variables de tipus primitius, resoldre aquest problema s simple. Perconvenci, se li assigna inicialment el valor 0 i ms endavant ja se sobreescriur elseu valor amb un altre vlid. Ara b, per al cas de variables complexes (com les detipus array o String), cal assignar un valor especial que en Java sanomena null.Aquesta cadena de text s una paraula reservada del llenguatge que serveix per dirque, de moment, la variable est declarada per ms endavant ja se li assignar unvalor correcte, tan aviat com sigui possible.

    Operar amb qualsevol variable de tipus complex amb un valor null assignatsempre resultar en un programa erroni.

    Per exemple, suposeu que voleu modificar el programa anterior de manera que,en lloc dentrar deu valors pel teclat, en podeu entrar un nombre arbitrari. A

  • Programaci bsica (ASX)Programaci (DAM) 26 Programaci modular

    partir de la seqncia escrita, el primer valor indicar quants enters cal llegir totseguit pel teclat. En un cas com aquest, s impossible inicialitzar larray amb unamida concreta, ja que aquesta depn duna entrada pel teclat. Per el programarequereix que aquest sigui declarat com una variable global. Per tant, cal diferirla inicialitzaci.

    El codi que resol aquesta situaci seria el segent. Ats que llegir la seqnciadenters del teclat ara s un problema ms complex, cal llegir la mida i els valors.Sha aplicat disseny descendent per dividir-lo en dos subproblemes: llegir la midade la seqncia i la seqencia prpiament. Comproveu que funciona en el vostreentorn de treball.

    1 //Variable global. Array no inicialitzat.2 private int[] llistaEnters = null;3 //En aplicar disseny descendent, ara cal declarar "lector" com a global4 Scanner lector = new Scanner(System.in);5 public static void main (String[] args) {6 OrdenarDescendentVariable programa = new OrdenarDescendentVariable();7 programa.inici();8 }9 public void inici() {

    10 llegirLlista();11 ordenarLlista();12 mostrarLlista();13 }14 //Mtode amb les instruccions per llegir la llista.15 //El primer valor sera la llargria16 public void llegirLlista() {17 System.out.println("Escriu una llista de valors enters i prem retorn.");18 System.out.println("El primer valor indica la mida de la seqncia.");19 llegirMida();20 llegirValors();21 }22 public void llegirMida() { //Metode que llegeix el primer valor23 //Lectura24 int mida = 0;25 if (lector.hasNextInt()) {26 mida = lector.nextInt();27 } else {28 lector.next();29 }30 llistaEnters = new int[mida]; //Inicialitizaci diferida de larray31 }32 public void llegirValors() {33 int index = 0;34 while (index < llistaEnters.length) {35 if (lector.hasNextInt()) {36 llistaEnters[index] = lector.nextInt();37 index++;38 } else {39 lector.next();40 }41 }42 lector.nextLine();43 } //La resta de mtodes no canvien ...44 }

  • Programaci bsica (ASX)Programaci (DAM) 27 Programaci modular

    1.3 Un exemple ms complex

    Un cop ja sha vist un exemple senzill daplicaci de disseny descendent, b-sicament amb lobjectiu dintroduir la sintaxi per a la declaraci de mtodes ivariables globals en Java, s el moment de proposar-ne un altre de ms complex,que requereixi diversos graus de descomposici.

    El que es vol fer s un gestor de registre de temperatures preses setmanalment perun observatori. Es pressuposa que el programa es posa en marxa a linici de lany(1 de gener) i al principi de cada setmana. Al llarg de 52 setmanes que t un any,es van enregistrant les temperatures mesurades cada dia de la setmana anterior (osigui, set en total cada vegada). Cada cop que es fa un registre, sabent que ha passatuna setmana, el programa calcula automticament quin dia i mes s lactual. Apartir daquestes dades, s possible consultar en qualsevol moment quina ha estatla temperatura mitjana i la diferncia entre el valor mxim i mnim enregistrats.En fer-ho, la data actual tamb es mostra en pantalla.

    Totes aquestes accions es porten a terme usant un men. Evidentment, laplicaciha de ser prou robusta com per tractar casos erronis (per exemple, consultar valorsquan encara no hi ha cap data enregistrada, o intentar registrar com a temperaturavalors de tipus incorrecte).

    Per deixar ms clar el comportament esperat, tot seguit es mostra un prototip delque sesperaria mostrar amb la seva execuci:

    1 Benvingut al registre de temperatures2 3 [RT] Registrar temperatures setmanals.4 [MJ] Consultar temperatura mitjana.5 [DF] Consultar diferncia mxima.6 [FI] Sortir.7 Opci: MJ8 No hi ha temperatures registrades.9

    10 Benvingut al registre de temperatures11 12 [RT] Registrar temperatures setmanals.13 [MJ] Consultar temperatura mitjana.14 [DF] Consultar diferncia mxima.15 [FI] Sortir.16 Opci: RT17 Escriu les temperatures daquesta setmana:18 20,5 21,1 21 21,7 20,9 20,6 19,919

    20 Benvingut al registre de temperatures21 22 [RT] Registrar temperatures setmanals.23 [MJ] Consultar temperatura mitjana.24 [DF] Consultar diferncia mxima.25 [FI] Sortir.26 Opci: MJ27 Fins avui 8 de gener la mitjana ha estat de 20.814285 graus.28

    29 Benvingut al registre de temperatures30 31 [RT] Registrar temperatures setmanals.32 [MJ] Consultar temperatura mitjana.33 [DF] Consultar diferncia mxima.

  • Programaci bsica (ASX)Programaci (DAM) 28 Programaci modular

    34 [FI] Sortir.35 Opci: DF36 Fins avui 8 de gener la diferncia mxima ha estat de 1.8000011 graus.37

    38 Benvingut al registre de temperatures39 40 [RT] Registrar temperatures setmanals.41 [MJ] Consultar temperatura mitjana.42 [DF] Consultar diferncia mxima.43 [FI] Sortir.44 Opci: FI

    1.3.1 Descomposici de problema

    Un cop sha plantejat amb cert detall el problema a resoldre (qu ha de fer elprograma), s possible iniciar la descomposici mitjanant disseny descendent.Per veure amb ms detall el procs, aquesta vegada sanir fent a poc a poc i nivellper nivell.

    1. Identificaci de les dades a tractar

    Abans de comenar la descomposici, com a pas previ, s interessant establirquina mena de dades cal manipular i com emmagatzemar-les dins el programa.Daquesta manera, resulta ms fcil avaluar per cada subproblema qu ha de dur aterme i si es tracta duna tasca complexa o no. En aquest cas, cal gestionar dunallista de temperatures, que es pot emmagatzemar usant un array de reals, i unadata dins un mateix any, que es pot emmagatzemar usant dos enters, dia i mes.Larray haur de tenir espai per emmagatzemar els valors dels dies a 52 setmanes(52*7 = 364) i caldr controlar el fet que hi ha posicions buides i daltres ambvalors correctes assignats. Per exemple, desprs de la primera setmana noms els7 primers valors, les posicions 0 a 6, sn vlids. La resta de posicions no tenenvalors vlids assignats.

    Quan arribi el moment caldr considerar si declarar-les com a variables globals,depenent de si aquestes dades susen dins de ms dun subproblema o no.

    2. Primer nivell de descomposici

    El resultat daplicar el primer nivell de descomposici pot resultar en molts opocs subproblemes depenent del grau de granularitat amb qu decidiu tractarles tasques que realitza el programa. Inicialment, s recomanable no usar unagranularitat alta i mantenir un nivell dabstracci alt. Normalment, s importantno baixar rpidament de nivell i comenar a resoldre problemes molt concrets enuna sola passada. Una estratgia per evitar aix es plantejar-se quines accions calemprendre abans de poder-ne dur a terme unes altres.

    Partint de la descripci del problema, una possible descomposici en nivells seriala segent, encara fora general. El programa bsicament s una estructura derepetici que va iterant sobre aquestes dues tasques:

  • Programaci bsica (ASX)Programaci (DAM) 29 Programaci modular

    Mostrar men.

    Tractar ordre.

    Aquestes iteracions saniran repetint fins a complir la condici que vol finalitzarel programa. Dentrada, es pot decidir que aix es dur a terme amb una variablede control de tipus semfor.

    Fins a cert punt, per a un dissenyador novell, seria comprensible proposar ja enel primer nivell resoldre subproblemes tals com el clcul de les temperaturesmnimes i mximes, ja que sn aspectes que ressalten clarament a lenunciat.Per si reflexioneu, us adonareu que per poder dur a terme aquestes tasques hiha condicions prvies que abans cal complir: que lusuari hagi seleccionat unaopci. Per tant, aix vol dir que gestionar el men i executar les opcions t relacide jerarquia dins el disseny: primer llegiu lopci i desprs lexecuteu. Per tant,no es troben en el mateix nivell.

    3. Segon nivell de descomposici

    Per veure si cal un segon nivell cal avaluar si els subproblemes proposats en elprimer nivell sn massa complexos encara. Evidentment, depenent de la destresadel programador, el que es considera complex pot ser molt relatiu. En qualsevolcas, i aix s independent de lhabilitat del programador, el que cal identificar sntasques clarament diferenciades que cal resoldre per solucionar cada subproblema.

    Mostrar men. Per fer aix, bsicament noms cal imprimir un conjunt detext en pantalla i ja est. s una tasca molt simple que es pot dur a termemitjanant successives invocacions a System.out.println. Per tant, nocal descompondre-la ms.

    Tractar ordre. Cal llegir lordre pel teclat i cal analitzar si el que es llegeixes correspon a alguna de les quatre ordres possibles. Aix es pot fer ambuna estructura de selecci. Llavors, segons el que sha llegit, cal fer tasquestotalment diferents. Clarament, es tracta duna tasca complexa que caldescompondre. La manera ms lgica de fer-ho, inicialment, podria serper cada tasca que cal dur a terme.

    A partir daquesta anlisi, la descomposici fins al segon nivell quedaria com:

    1. Mostrar men.

    2. Tractar ordre.

    (a) Entrar registre de temperatures setmanals.

    (b) Mostrar temperatura mitjana.

    (c) Mostrar diferncia mxima.

    (d) Finalitzar execuci.

  • Programaci bsica (ASX)Programaci (DAM) 30 Programaci modular

    4. Tercer nivell de descomposici

    Novament, es fa una iteraci sobre els subproblemes de segon nivell per veure sipresenten tasques complexes o no. En funci daix, caldr decidir si cal seguirdescomposant-los.

    Entrar registre de temperatures setmanals. Per fer aix cal resoldredues tasques. Duna banda, llegir les temperatures i posar-les a larray detemperatures. A ms, tamb cal anar actualitzant la data actual cada copque es llegeixen dades (avanar-la 7 dies). Aix no s simple, ja que calcontrolar el cas de quin dia acaba cada mes (28, 30 o 31 dies).

    Mostrar temperatura mitjana. Aquest problema es pot descompondre endos. Duna banda, es demanamostrar la data demanera que el mes esmostrien format text, partint dun nmero. Daltra banda, cal mostrar el clcul quees demana (sumar tots els valors a larray de temperatures i dividir-los pelseu nombre).

    Mostrar diferenciamxima. Aquest cas s exactament igual que lanterior,noms que el clcul s diferent (cercar amb un nic recorregut els valorsmxim i mnim i calcular-ne la diferncia).

    Finalitzar execuci. Bsicament, seria canviar el valor de la variable decontrol de tipus semfor que controla lestructura de repetici on sengloba-ran Mostrar men i Tractar ordre. s molt simple.

    Segons aquesta anlisi, la descomposici fins al tercer nivell quedaria aix:

    1. Mostrar men.

    2. Tractar ordre.

    (a) Entrar registre de temperatures setmanals.i. Llegir temperatures del teclat.ii. Actualitzar data actual.

    (b) Mostrar temperatura mitjana.i. Mostrar data actual.ii. Calcular temperatura mitjana.

    (c) Mostrar diferncia mxima.i. Mostrar data actual.ii. Calcular diferncia mxima.

    (d) Finalitzar execuci.

    5. Quart nivell de descomposici

    Novament, correspon estudiar si cal fer un nou nivell de descomposici segonsel grau de complexitat dels subproblemes de tercer nivell. Un punt interessantque ara us trobeu s el fet que es poden localitzar subproblemes repetits. Mostrarla data actual s una tasca que cal fer en llocs diferents. Per tant, noms caldrresoldre aquest subproblema una nica vegada.

  • Programaci bsica (ASX)Programaci (DAM) 31 Programaci modular

    Llegir temperatures del teclat. Tot i que no es fa en poques lnies de codi,sabeu llegir 7 valors de tipus real i assignar-los a un array. Per tant, no suna tasca especialment complexa que valgui la pena descompondre ms.

    Actualitzar data actual. Es tracta dincrementar el dia i, depenent del mes,amb una estructura de selecci, veure si sha avanat a un nou mes. No escompon de passes gaire complexes.

    Mostrar data actual. Es tracta de mostrar el dia directament i mostrar certtext segons el valor numric del ms. Aix es podria fer amb una estructurade selecci. Per tant, tampoc es compon de passes gaire complexes..

    Calcular temperatura mitjana. s un clcul sobre els valors registrats,fent un recorregut sobre larray. s simple.

    Calcular diferncia mxima. Exactament un cas molt semblant a lanteri-or.

    Ats que tots els subproblemes del tercer nivell ja sn simples i resolen una tascamolt concreta i autocontinguda, no cal un quart nivell de descomposici. Heuacabat.

    1.3.2 Esquelet de la classe

    Un cop identificades les dades que es volen tractar i finalitzat el procs dedescomposici inicial, s possible crear un esquelet de la classe, noms amb ladeclaraci de variables globals i mtodes necessaris. Cada subproblema equivala un mtode que cal declarar. Si lesquelet est correctament declarat, hauria deser possible compilar el codi font, tot i que en executar-se no faria absolutamentres encara. Noms es tracta duna organitzaci general del codi font.

    En aquest exemple lesquelet quedaria aix:

    1 public class RegistreTemperatures {2

    3 //Constants4 private static final int MAX_SETMANES = 52;5

    6 //Variables globals7 private int numTemperatures = 0;8 private float[] temperatures = new float[MAX_SETMANES * 7];9 private int dia = 1;

    10 private int mes = 1;11

    12 //Mtodes associats al problema general13 public static void main (String[] args) {14 RegistreTemperatures programa = new RegistreTemperatures();15 programa.inici();16 }17 public void inici() {18 }19

    20 //Mtodes associats al primer nivell de descomposici21 public void mostrarMenu() {22 }

  • Programaci bsica (ASX)Programaci (DAM) 32 Programaci modular

    23 public void tractarOpcio() {24 }25

    26 //Mtodes associats al segon nivell de descomposici27 public void registreTemperaturesSetmanals() {28 }29 public void mostrarMitjana() {30 }31 public void mostrarDiferencia() {32 }33 public void finalitzarExecuci() {34 }35

    36 //Mtodes associats al tercer nivell de descomposici37 //etc.38 }

    Repte 2: Completeu el codi font de lesquelet de lexemple amb ladeclaraci dels mtodes al tercer nivell de descomposici. Els seusnoms seran: llegirTemperaturesTeclat, incrementarData, mostrarData,calculaMitjana i calculaDiferencia.

    1.3.3 Implementaci del tercer nivell de descomposici

    Per codificar la descomposici daquest problema, tamb es comenar des delsmtodes associats als subproblemes del nivell ms baix de descomposici i sanirpujant a poc a poc fins a arribar a la resoluci del problema general, que corresponal mtode principal. Per tant, cal codificar els mtodes:

    llegirTemperaturesTeclat: registra 7 temperatures, o sigui, llegeix 7valors reals i els desa a larray de temperatures.

    incrementarData: donada una data, suma 7 al seu valor.

    mostrarData: mostra la data actual, en format: Nmero del dia de Nomdel mes.

    calculaMitjana: mostra per pantalla la mitjana aritmtica de temperatu-res del registre.

    calculaDiferencia: mostra per pantalla la diferncia de temperaturesentre els valors mxim i mnim del registre.

    Una proposta de com fer el seu codi seria la segent: ats que elsmtodes sn blocsautocontiguts de codi, un cop incorporats al codi font del programa, s possiblecompilar-lo perfectament sense problemes, tot i que, evidentment, el programaencara no far res si sexecuta. Afegiu-los i comproveu que s aix.

    1 //Mtodes associats al tercer nivell de descomposici2 public void llegirTemperaturesTeclat() {3 System.out.println("Escriu les temperatures daquesta setmana:");4 Scanner lector = new Scanner(System.in);5 int numLlegides = 0;6 while (numLlegides < 7) {7 if (lector.hasNextFloat()) {

  • Programaci bsica (ASX)Programaci (DAM) 33 Programaci modular

    8 temperatures[numTemperatures] = lector.nextFloat();9 numLlegides++;

    10 numTemperatures++;11 } else {12 lector.next();13 }14 }15 lector.nextLine();16 }17 public void incrementarData() {18 //Quants dies t aquest mes?19 int diesAquestMes = 0;20 if (mes == 2) {21 diesAquestMes = 28;22 } else if ((mes == 4)||(mes == 6)||(mes == 9 )||(mes == 11)) {23 diesAquestMes = 30;24 } else {25 diesAquestMes = 31;26 }27 dia = dia + 7;28 //Hem passat de mes?29 if (dia > diesAquestMes) {30 dia = dia diesAquestMes;31 mes++;32 //Hem passat dany?33 if (mes > 12) {34 mes = 1;35 }36 }37 }38 public void mostrarData() {39 System.out.print(dia + " de ");40 switch(mes) {41 case 1:42 System.out.print("Gener"); break;43 case 2:44 System.out.print("Febrer"); break;45 case 3:46 System.out.print("Mar"); break;47 case 4:48 System.out.print("Abril"); break;49 case 5:50 System.out.print("Maig"); break;51 case 6:52 System.out.print("Juny"); break;53 case 7:54 System.out.print("Juliol"); break;55 case 8:56 System.out.print("Agost"); break;57 case 9:58 System.out.print("Setembre"); break;59 case 10:60 System.out.print("Octubre"); break;61 case 11:62 System.out.print("Novembre"); break;63 case 12:64 System.out.print("Desembre");65 }66 }67 public void calculaMitjana() {68 float acumulador = 0;69 for(int i = 0; i < numTemperatures; i++) {70 acumulador = acumulador + temperatures[i];71 }72 System.out.print((acumulador / numTemperatures));73 }74 public void calculaDiferencia() {75 //Veure Repte 3, ms endavant76 //...77 }

  • Programaci bsica (ASX)Programaci (DAM) 34 Programaci modular

    Repte 3: Codifiqueu el mtode calculaDiferencia. Explicat amb ms detall,aquest mtode cerca els valors ms alt i ms baix dentre els enregistrats i calculala diferncia entre ells. Un cop calculat, mostra el valor resultant per pantalla, talcom fa calculaMitjana.

    1.3.4 Implementaci del segon nivell de descomposici

    Un cop acabada la codificaci dels mtodes de nivell ms baix de descomposici,cal resoldre el nivell immediatament superior, pas a pas, sense saltar-se capnivell. Un aspecte interessant en anar resolent nivells superiors s que, si ladescomposici ha estat apropiada, la dificultat de codificar tots els subproblemes,independentment del nivell, hauria de ser similar. En el cas dels nivells msbaixos, aix era degut al fet que es tracta dels problemes que heu considerat mssimples, com ja heu vist. En nivell superiors, per, la seva complexitat tambser ms baixa ja que es disposa duna part del problema resolta. Per tant, lacodificaci daquest segon nivell no hauria de resultar haver de fer mtodes moltms complicats o necessriament amb ms codi que el pas anterior. De fet, fins itot poden ser ms senzills.

    Els mtodes que estan inclosos en aquest nivell sn els associats a les quatreopcions possibles dins el programa:

    registreTemperaturesSetmanals: gestiona el porcs de registrar tem-peratures setmanals: llegir dades, emmagatzemar-les i incrementar la dataactual.

    mostrarMitjana: mostra per pantalla el missatge de la mitjana de lestemperatures: data actual i valor.

    mostrarDiferencia: mostra per pantalla el missatge de la difernciamxima de les temperatures: data actual i valor.

    finalitzarExecuci: gestiona la finalitzaci del programa.

    La codificaci estrictament de nivells inferiors a superiors demaneratotalment compartimentalitzada no sempre s possible. ::: A mesura que aneupujant de nivells podeu trobar alguns casos especials, els quals no sn infreqentsdurant un procs de disseny descendent, i sobre ell us caldr reflexionar.

    Duna banda, es pot donar el cas en qu caldr aprofitar un mateix mtode denivells inferiors per codificar ms dun mtode del nivell present. Aquest s elcas de mostrarMitjana i mostrarDiferencia, ja que ambds han de mostrarla data actual, i per tant faran s de mostrarData.

    Daltra banda, la codificaci dun mtode pot no ser clara a priori, i no ho serfins a solucionar nivells de descomposici superiors. Aquest s el cas de lacodificaci del mtode finalitzarExecuci, ja que controla la finalitzaci delexecuci del programa principal, un mtode de nivell superior que encara no

  • Programaci bsica (ASX)Programaci (DAM) 35 Programaci modular

    toca implementar. Aquest s un cas en qu la resoluci ordenada de nivell inferiora superior individualment no s perfecta, ja que cal una visi ms general delproblema. Quan aix passa, cal deixar el codi buit fins que la soluci quedi msclara ms endavant.

    El codi dels quatre mtodes, que preveu les circumstncies tot just descrites, seriael segent. Afegiu-lo al programa i comproveu que compila correctament.

    1 //Mtodes associats al segon nivell de descomposici2 public void registreTemperaturesSetmanals() {3 //Cal controlar si hi haur espai per a aquests 7 registres4 if ((numTemperatures + 7) >= temperatures.length) {5 System.out.println("No queda espai per a ms temperatures.");6 } else {7 llegirTemperaturesTeclat();8 incrementarData();9 }

    10 }11 public void mostrarMitjana() {12 if (numTemperatures > 0) {13 System.out.print("\nFins avui ");14 mostrarData();15 System.out.print(" la mitjana ha estat de ");16 calculaMitjana();17 System.out.println(" graus.");18 } else {19 System.out.println("\nNo hi ha temperatures registrades.");20 }21 }22 public void mostrarDiferencia() {23 //Veure Repte 4, tot seguit.24 //...25 }26 public void finalitzarExecuci() {27 //Ja es pensar a resoldre el nivell superior...28 }

    Repte 4: Codifiqueu el mtode mostrarDiferencia.

    1.3.5 Implementaci del primer nivell de descomposici

    En aquest problema, el primer nivell de descomposici es correspon als subpro-blemes ms generals, que engloben totes les funcions del programa. Noms calimplementar dos mtodes:

    mostrarMenu: mostra el men principal per pantalla (noms imprimeixcoses per pantalla).

    tractarOpcio: llegeix lordre i executa el mtode de segon nivell corres-ponent.

    El codi que porta a terme aquestes tasques s el segent. Fixeu-vos que encarano heu resolt el mtode finalitzarExecuci, per ats que se nha declaratlesquelet, es pot invocar correctament sense que hi hagi cap error de compilaci.Simplement, ara per ara la seva invocaci s equivalent a no fer res (no sexecutacap instrucci).

  • Programaci bsica (ASX)Programaci (DAM) 36 Programaci modular

    equalsIgnoreCase

    Aquest mtode de la classeString compara dues cadenes

    de text ignorant diferncies entremajscules i minscules.

    1 //Mtodes associats al primer nivell de descomposici2 public void mostrarMenu() {3 System.out.println("\nBenvingut al registre de temperatures");4 System.out.println("");5 System.out.println("[RT] Registrar temperatures setmanals.");6 System.out.println("[MJ] Consultar temperatura mitjana.");7 System.out.println("[DF] Consultar diferncia mxima.");8 System.out.println("[FI] Sortir.");9 System.out.print("Opci: ");

    10 }11 public void tractarOpcio() {12 Scanner lector = new Scanner(System.in);13 String opcio = lector.nextLine();14 if (opcio.equalsIgnoreCase("RT")) {15 registreTemperaturesSetmanals();16 } else if (opcio.equalsIgnoreCase("MJ")) {17 mostrarMitjana();18 } else if (opcio.equalsIgnoreCase("DF")) {19 mostrarDiferencia();20 } else if (opcio.equalsIgnoreCase("FI")) {21 finalitzarExecuci();22 } else {23 System.out.println("Opci incorrecta!\n");24 }25 }

    1.3.6 Implementaci del problema general

    Finalment, ha arribat el moment dimplementar el problema general, el mtodeinici. Ats que tots els subproblemes inferiors ja han estat resolts, normalmentaquesta tasca ser ja relativament simple. Pel funcionament que sha definit pera aquest programa, el que ha de fer bsicament s mostrar el men i llegir unaordre de manera indefinida, fins a demanar que finalitzi el programa, o sigui unaestructura de repetici controlada per una variable de control amb funcions desemfor, que canviar destat quan calgui finalitzar les iteracions.

    El seu codi seria el segent, on fi seria la variable de control. Com podeu veure,aquest s el mtode ms senzill de tots!

    1 public void inici() {2 while (!fi) {3 mostrarMenu();4 tractarOpcio();5 }6 }

    Un cop arribats a aquest punt, toca fer marxa enrere i recordar que hi havia unatasca pendent: codificar finalitzarExecuci. Les seves instruccions no espodien deduir en el seu moment, ja que depenien de com es resoldria el codi delproblema general. Ara que ja sabeu que la finalitzaci del programa depn dunavariable de control, ja es pot saber que cal canviar el seu valor de manera adient.

  • Programaci bsica (ASX)Programaci (DAM) 37 Programaci modular

    Per tant, el seu codi ser:

    1 public void finalitzarExecuci() {2 fi = true;3 }

    Un cop codificat, noms resta una cosa, i s declarar aquesta variable. Ats que estracta dun valor que cal accedir des de dos mtodes diferents, caldr fer-ho comuna variable global.

    1 //Variables globals2 private boolean fi = false;3 private int numTemperatures = 0;4 private float[] temperatures = new float[MAX_SETMANES * 7];5 private int dia = 1;6 private int mes = 1;7 ...

    1.3.7 Millores sobre la soluci final

    Un cop finalitzat el programa, s el moment de veure si funciona. Evidentment,pot ser que el codi dalgun mtode no hagi estat codificat correctament i siguinecessari corregir-lo. Per al cas dels programes complexos, el depurador s unaeina de gran ajut en aquest tasca, complementada amb el fet que, usant mtodes,s molt fcil identificar la utilitat de cada bloc de codi.

    Tot i que el programa funcioni, un cop ja disposeu de tot el codi del programa (jashan dedut tots els mtodes, el seu codi, i les variables globals que cal usar), val lapena donar una ullada general per refinar el resultat. Aquest procs de refinamentes basa en dos principis: eliminar mtodes massa curts o simplificar els que snencara massa llargs o complexos.

    Abans de procedir a millorar el codi, per, cal que tingueu sempre present lamxima segent: primer cal que el programa funcioni. Desprs ja pensareucom simplificar el codi.

    Eliminaci de mtodes

    Un cop codificats tots els mtodes, potser hi haur algun que t molt poques lnies-estem parlant duna o dues. Mai es reaprofita, i noms susa en un nic lloc.Normalment, quan aix passa es deu al fet que sha filat massa prim en el procs dedescomposici i sha considerat com a subproblema una tasca que s molt senzillai no t prou entitat en si mateixa. Que aix succeeixi no vol dir que el procs hagiestat totalment incorrecte, ja que moltes vegades, a priori, s impossible saberque aix passar. Molts cops, noms un cop codificats tots els mtodes us podeuadonar daquest fet i obrar en conseqncia.

  • Programaci bsica (ASX)Programaci (DAM) 38 Programaci modular

    A la secci Recursos delcontingut del web

    disposeu dun annex onsexplica una tcnica per

    simplificar el codi dalgunsmtodes amb estructures

    de selecci llargues.

    Un cas clar daquesta circumstncia pot ser el mtode finalitzarExecuci, quenoms t una lnia i noms sinvoca en un nic lloc dins el programa. Normalment,no t sentit crear mtodes tan curts. Per tant, no seria incorrecte eliminar-lo iincorporar el seu codi directament all on sinvoca (en el tractament de lordreFI).

    1 public void tractarOpcio() {2 Scanner lector = new Scanner(System.in);3 String opcio = lector.nextLine();4 if (opcio.equalsIgnoreCase("RT")) {5 registreTemperaturesSetmanals();6 } else if (opcio.equalsIgnoreCase("MJ")) {7 mostrarMitjana();8 } else if (opcio.equalsIgnoreCase("DF")) {9 mostrarDiferencia();

    10 } else if (opcio.equalsIgnoreCase("FI")) {11 //Sha esborrat el mtode finalitzarExecuci i sha posat el seu codi

    directament.12 fi = true;13 } else {14 System.out.println("Opci Incorrecta!\n");15 }16 }

    Millora de mtodes

    Si al final del procs apareix algunmtodemolt llarg o complex, aix pot significarel contrari del cas anterior: que no sha descomposat prou el problema. Pot valerla pena tornar a aplicar el procs de descomposici a posteriori, dividint aquestmtode en daltres. Tot i que pot semblar que, un cop el programa ja funciona, noval la pena refinar el procs de descomposici (al cap i a la fi, el seu propsit erasimplificar el procs de creaci, que ja ha finalitzat), penseu que un altre avantatgedel disseny descendent s facilitar la legibilitat del vostre codi. En el mn de laprogramaci tampoc us ha de fer mandra de ser polits i endreats (amb el vostrecodi).

    Ara b, de vegades el procs ha estat correcte i simplement la quantitat de lnies decodi necessries per dur a terme la tasca establerta s realment gran. En casos comaquests, igualment, s interessant repassar si el codi es pot millorar simplificant-lo, cercant algun conjunt de codi alternatiu que el faci ms curt. Evidentment,aix no sempre s possible, per val la pena fer-hi una pensada ara que ja teniu unprograma que funciona.

  • Programaci bsica (ASX)Programaci (DAM) 39 Programaci modular

    1.4 Soluci dels reptes proposats

    Repte 1

    1 import java.util.Scanner;2 public class OrdenarDescendent {3 int[] llistaEnters = new int[10];4 public static void main (String[] args) {5 OrdenarDescendent programa = new OrdenarDescendent();6 programa.inici();7 }8 public void inici() {9 llegirLlista();

    10 ordenarLlista();11 mostrarLlista();12 comptarMeitatMaxim();13 }14 //Mtode amb les instruccions per llegir la llista.15 public void llegirLlista() {16 System.out.println("Escriu 10 valors enters i pitja retorn.");17 Scanner lector = new Scanner(System.in);18 int index = 0;19 while (index < llistaEnters.length) {20 if (lector.hasNextInt()) {21 llistaEnters[index] = lector.nextInt();22 index++;23 } else {24 lector.next();25 }26 }27 lector.nextLine();28 }29 //Mtode amb les instruccions per ordenar la llista.30 public void ordenarLlista() {31 for (int i = 0; i < llistaEnters.length 1; i++) {32 for(int j = i + 1; j < llistaEnters.length; j++) {33 //La posici tractada t un valor ms alt que el de la cerca... Els

    intercanviem.34 if (llistaEnters[i] > llistaEnters[j]) {35 //Per intercanviar valors cal una variable auxiliar36 int canvi = llistaEnters[i];37 llistaEnters[i] = llistaEnters[j];38 llistaEnters[j] = canvi;39 }40 }41 }42 }43 //Mtode amb les instruccions per mostrar la llista per pantalla.44 public void mostrarLlista() {45 System.out.print("Larray ordenat es: [ ");46 for (int i = 0; i < llistaEnters.length;i++) {47 System.out.print(llistaEnters[i] + " ");48 }49 System.out.println("]");50 }51 //Nou mtode per resoldre el nou subproblema52 public void comptarMeitatMaxim() {53 int valorMaxim = llistaEnters[llistaEnters.length 1] / 2;54 int i = 0;55 while ((llistaEnters[i] < valorMaxim)&&(i < llistaEnters.length)) {56 i++;57 }58 System.out.println("El nombre de valors inferiors a la meitat del maxim s

    " + i);59 }60 }

  • Programaci bsica (ASX)Programaci (DAM) 40 Programaci modular

    Repte 2

    1 ...2 //Mtodes associats al tercer nivell de descomposici3 public void llegirTemperaturesTeclat() {4 }5 public void incrementarData() {6 }7 public void mostrarData() {8 }9 public void calculaMitjana() {

    10 }11 public void calculaDiferencia() {12 }13 ...

    Repte 3

    1 public void calculaDiferencia() {2 float maxima = temperatures[0];3 float minima = temperatures[0];4 for(int i = 1; i < numTemperatures; i++) {5 if (temperatures[i] < minima) {6 minima = temperatures[i];7 }8 if (temperatures[i] > maxima) {9 maxima = temperatures[i];

    10 }11 }12 System.out.print((maxima minima));13 }

    Repte 4

    1 public void mostrarDiferencia() {2 if (numTemperatures > 0) {3 System.out.print("\nFins avui ");4 mostrarData();5 System.out.print(" la diferncia mxima ha estat de ");6 calculaDiferencia();7 System.out.println(" graus.");8 } else {9 System.out.println("\nNo hi ha temperatures registrades.");

    10 }11 }

  • Programaci bsica (ASX)Programaci (DAM) 41 Programaci modular

    2. Parametritzaci de mtodes

    Lobjectiu principal del disseny descendent s oferir una metodologia que uspermeti plantejar la creaci dun programa duna manera molt semblant a com hofareu amb qualsevol altre problema de la vida real: dividint problemes complexosen daltres ms simples i fcils de seguir. Un cop sha fet aquesta descomposici,els llenguatges ofereixen un mecanisme per associar a cada subproblema un blocde codi concret. En Java, es tracta dels mtodes. El benefici dusar mtodes, en lamesura correcta, s la generaci de codi ms fcil dentendre i on pot ser possiblereutilitzar alguns blocs a diferents parts, sense haver de repetir el codi escrit.

    Si b la identificaci de subproblemes dacord a diferents nivells de complexitats suficient per poder descompondre el programa en bocins de codi amb objectiusparcials diferenciats, i fer-lo ms fcil de seguir, no s suficient per oferir unalt grau de reusabilitat. En la majoria de casos, el programa resultant dividitamb mtodes s directament equivalent a trossejar un programa on noms hi hael mtode principal. Aix es deu al fet que tal com heu usat els mtodes finsara, aquests servien per manipular un conjunt de variables, sovint globals, moltespecfic.

    En realitat, a lhora de plantejar quins subproblemes hi ha, i la seva declaraciassociada en forma de mtode al codi, a part del seu nom i qu fan, tamb spossible definir certs aspectes vinculats a les dades que han de tractar: els seusparmetres dentrada i de sortida.

    Un parmetre s un identificador usat dins la descripci dun procs, elvalor del qual en realitat pot variar per diferents aplicacions daquest procs.

    2.1 Parmetres dentrada

    Els parmetres dentrada sn una eina molt til i extensament usada a lhora dedefinir amb ms detall les caracterstiques dels subproblemes resultants dunadescomposici usant disseny descendent. Per comenar, i com a resum breudaquest concepte, podeu quedar-vos amb la definici segent.

    Un parmetre dentrada s un valor que sestableix immediatament abansde seguir un procs, de manera que indica les dades que ha de tractar o quemodifica el seu comportament.

    Laparici de blocs de codirepetit o gaireb igual indicaun mal estil de programaci.

  • Programaci bsica (ASX)Programaci (DAM) 42 Programaci modular

    2.1.1 Motivaci: definici de problemes semblants

    Si es descompon fins a dos nivells el problema de cuinar uns fideus japonesosvegetals, es podrien trobar els subproblemes segents:

    1. Recopilar ingredients

    (a) Comprar al supermercat

    (b) Disposar-los sobre el marbre

    2. Cuinar tallarines

    (a) Preparar aigua

    (b) Bullir tallarines

    (c) Escrrer tallarines

    (d) Deixar-les preparades

    3. Cuinar pastanagues

    (a) Tallar pastanagues

    (b) Fregir pastanagues

    (c) Deixar pastanagues preparades

    4. Cuinar cebes

    (a) Tallar cebes

    (b) Fregir cebes

    (c) Deixar cebes preparades

    5. Preparaci final

    (a) Barrejar ingredients amb salsa yakitori

    (b) Saltar ingredients

    (c) Preparar paella per saltar

    (d) Cuinar remenant ingredients

    (e) Deixar llest per servir

    Partint daquest plantejament, la figura 2.1 mostra la divisi ja ms detallada, finsa un tercer nivell, dels processos de fregir cebes i pastanagues, usats en llocsben diferents (3 i 4). En aquesta figura hi ha remarcades mitjanant quadres lesdiferncies entre tots dos.

  • Programaci bsica (ASX)Programaci (DAM) 43 Programaci modular

    Figura 2.1. Diferncies entre dos problemes semblants.

    Ja a simple vista es pot veure que, tot i poder descompondres fins en sis noussubproblemes, es tracta de dos procediments molt semblants. De fet, si analitzeuamb detall els dos casos, us adonareu que noms canvia laliment que cal fregir,per els subproblemes que cal anar resolent sn exactament els mateixos en tots elscasos. De fet, si tingussiu una certa visi de futur, podreu arribar a adonar-vosque aquest escenari saplicaria fins i tot en descomposicions daltres procedimentssemblants que no us cal usar aqu, com, per exemple, fer patates fregides. Lnicacondici s que, quan parleu de fregir, sempre heu destar-vos referint a aliments,s clar.

    Dit en paraules informtiques: donats aquests dosmtodes, noms varia el valor deles dades que cal transformar, que sempre seran didntic tipus. Per lalgorismeque cal usar s el mateix.

    La conseqncia daquesta observaci s que seria molt ms cmode definir unseguit de passes de manera genrica. Per exemple, anomenar el procs fregiraliment, on noms susa el terme aliment dins de la descripci de les seves passesper referir-se a all que es vol fregir. Llavors, sempre que es vol fregir un alimentconcret, en les explicacions es reemplaa on posa aliment per all que realment esvol fregir (cebes, pastanagues, patates, etc.) i saplica el procs tal com est escrit,sense haver de canviar res. Una nica descripci serveix per fregir qualsevol cosa,no cal descriure un cas diferent per cada aliment.

    Doncs b, si fssiu aix, el terme aliment encaixaria amb la definici de parmetredentrada. El seu valor sestableix abans de comenar el procs, i segons aquest,condiciona all que cal tractar (en aquest cas, fregir).

    Un fet important en un cas com aquest s que el nombre de parmetres dentradapermesos no t perqu estar limitat a un. Podreu definir tants com us facin faltaper cada diferncia existent, o per cada dada addicional que pugui variar segons lasituaci i que cal tenir en compte per realitzar-lo. Per exemple, suposeu que voleupreveure la possibilitat de fregir amb diferents quantitats doli. O sigui, solucionarel problema fregir aliment amb certa quantitat doli. En aquest cas, es podrien

  • Programaci bsica (ASX)Programaci (DAM) 44 Programaci modular

    s molt important triarcorrectament el nom dels

    subproblemes, perqusiguin descriptius.

    usar dos parmetres dentrada: laliment i la quantitat doli. Les passes a seguircontinuarien essent gaireb iguals, llevat que la descripci seria genrica tant alhora de referir-se a laliment que cal fregir, com pel que fa a quant doli cal posara la paella. Aix, doncs, la descripci del procs seria independent tant quant aqu cal fregir com pel que fa a la quantitat doli a usar. Els valors concrets que calaplicar dependrien de cada situaci donada a lhora de fregir:

    Fregir patates amb 400 cl doli: (aliment = patates, quantitat = 400 cl).

    Fregir cebes amb 200 cl doli : (aliment = cebes , quantitat = 200 cl).

    Fregir escalopes amb 400 cl doli: (aliment = escalopes, quantitat = 400 cl).

    Etc.

    Per tant, un cop teniu dividit un problema general en subproblemes, caldr estudiarquins dells sn prou semblants per, en realitat, poder considerar que es tracta delmateixmitjanant laplicaci de parmetres dentrada. Normalment, si el nom quesha posat als subproblemes s adient, aix s fcil de detectar, ja que en tindran demolt semblants, o fins i tot idntics. Pot succeir que les divisions en subproblemesno siguin exactament idntiques com en aquest exemple, per llavors valdr lapena que reviseu la descomposici i reflexioneu sobre si, en realitat, hauria de serigual.

    A mesura que tingueu experincia, no us caldr ni tan sols esperar al final i ja deben segur que anireu detectant aquestes semblances sobre la marxa.

    2.1.2 Declaraci i s de mtodes amb parmetres dentrada

    De la mateixa manera que aix estalvia molt despai en un llibre de cuina, aplicaraquest sistema en aplicar disseny descendent per descompondre un programatamb s molt til. Aix vol dir que aquest fet tamb sha de poder preveure a ladeclaraci i codificaci dun mtode. Per sort, tots els llenguatges de programacique permeten declarar funcions o mtodes preveuen aquesta possibilitat.

    Declaraci

    La llista de parmetres dun mtode sescriu entre els parntesis en la seva decla-raci. Aquesta llista pren una estructura semblant a fer un seguit de declaracionsde variables separades per comes. La sintaxi exacta seria la segent:

    1 public void nomMtode (tipusParam1 numParam1, tipusParam2 nomParam2, etc.) {2 //Codi3 ...4 }

    La declaraci de parmetres dentrada no s obligatria. Si no us calen parmetresdentrada per un mtode, no cal posar res entre els parntesis, tal com heu fet fins

  • Programaci bsica (ASX)Programaci (DAM) 45 Programaci modular

    ara. Tampoc hi ha lmit en el nombre de parmetres, per normalment s millorno excedir-se. De fet, un alt nombre de parmetres en el mtode associat a unsubproblema pot significar que no sha descompost suficientment.

    Un cop un mtode t definits un seguit de parmetres dentrada, aquests esconsideren variables declarades, amb mbit dins de tot el seu codi. Aquestesvariables poden ser usades com qualsevol altra dins el seu codi. Ara b, tenenuna peculiaritat, i s que dentrada no sels assigna cap valor inicial, ja que vindrdonat segons com sinvoqui el mtode, com veureu tot seguit.

    1 //El mtode mostrarMaxim t dos parmetres dentrada, de tipus enter2 public void mostrarMaxim(int a, int b) {3 ...4 }

    nicament pel que fa a variables disponibles dins del bloc de codi del mtode, espot considerar que aquest codi seria equivalent a fer:

    1 public void mostrarMaxim() {2 //Sinicialitzen amb un valor inicial duna manera especial que ja veureu

    aviat3 int a;4 int b;5 ...6 }

    Invocaci

    Quan un mtode sha declarat amb parmetres dentrada, cal tenir-los en comptedurant la seva invocaci. No hi ha prou a posar noms el nom del mtode com finsara. Per cada parmetre cal assignar un valor, exactament en el mateix ordre enqu shan declarat a la llista. Aquest valor pot ser el resultat de qualsevol expressi:un literal, una variable, o una expressi ms complexa. En qualsevol cas, eltipus resultant ha de coincidir amb el del parmetre que ocupa el mateix ordre.Sintcticament, aix es fa posant els valors entre els parntesis de la invocaci,separats per comes:

    1 nomMetode(valor1, valor2, etc.);

    Quan sinvoca un mtode amb un conjunt de parmetres dentrada declarats, elprimer que fa el programa s mirar la llista de parmetres i declarar, implcitamentdins el codi del mtode, tantes variables com parmetres dentrada, amb elsmateixos noms. Llavors agafa cada valor especificat a la invocaci i copia, unper un i en el mateix ordre, aquests valors dins les variables creades a partir de lallista de parmetres.

    La millor manera de tenir una primera idea de com funciona tot plegat s ambun exemple senzill. El codi segent serveix per illustrar el comportament dunmtode amb parmetres dentrada. No es tracta dun programa complex resultatdaplicar estrictament disseny descendent, noms serveix per provar com funciona.Comproveu qu fa en el vostre entorn de treball.

    El mtode principal (main)es declara amb unparmetre dentrada: unarray de String.

  • Programaci bsica (ASX)Programaci (DAM) 46 Programaci modular

    La figura 2.2, tot seguit, mostra un esquema del seu flux de control i qu estpassant a mesura que sexecuten les instruccions del p