Cappeli Federico



Scaricare 47 Kb.
24.01.2018
Dimensione del file47 Kb.

Cappeli Federico matr:107405



esperienza di progetto

Il problema:
In un primo approccio il progetto consiste nello sviluppo di un’astrazione orario, o se vogliamo l’orologio. In sostanza un orologio che riporta secondi minuti e ore non è altro che un insieme di contatori opportunamente collegati tra di loro e sincronizzati secondo un algoritmo di ovvia conoscenza. Quindi sarà necessario utilizzare la classe Counter precedentemente modellata per raggiungere questo primo obiettivo. Deve essere possibile fornire dei servizi da utilizzare sull’ADT Orologio.

In seconda battuta si vuole modellare una sorta di archivio costituito da N rilevamenti, avvenuti ad una tal ora, di temperature in gradi centigradi. Si ritiene utile anche fornire un servizio che possa comunicare la temperatura media sui rilevamenti effettuati.

Il tutto deve essere sfruttato da un componente software che crea un rilevamento con ore e temperature a scelta e fornisca la media di tali temperature.
Analisi:
Orologio.

L’orologio in questione è un oggetto composto, cioè è formato al suo interno da oggetti già precedentemente definiti, i contatori. I contatori come ADT sono stati il risultato finale della prima esperienza di progetto e quindi si è tranquilli che utilizzandoli avranno sicuramente comportamenti omologhi a quelli già esaminati. E’ quindi necessario definire, all’interno dell’astrazione orologio, le grandezze: ore, minuti, secondi (hour, minute, second) . Ognuna di queste deve costituire un riferimento al tipo Counter.

Questo fa si che java allochi nella memoria lo spazio necessario a tre riferimenti. Notare che sarà poi obbligatorio tramite vari costruttori con differenti parametri creare questi tre oggetti tramite l’invocazione di 3 new che istanziano oggetti nel nostro caso di classe Counter. In particolare si deve definire un costruttore di default, senza parametri che inizializza i tre Counter al valore 0; altri che diano la possibilità rispettivamente di inizializzare l’orologio a un qualsiasi orario avendo la possibilità di agire o sulle ore solamente o sulle ore e i minuti o su tutti e tre i campi.

Bisogna rendere disponibili agli utenti dei servizi che possono essere forniti la classe Orologio, in particolare la definizione di un metodo che simuli il movimento della lancetta dei secondi, che comprende l’algoritmo di facile comprensione per la sincronizzazione dei contatori. Significa che come un vero e proprio orologio quando il conteggio dei secondi arriva a 59 al prossimo incremento passi al valore 0 e incrementi i minuti. Analogamente per quanto riguarda il conteggio dei minuti e delle ore. Altro vincolo da imporre è che le ore devono avere un valore compreso uguale tra 0 e 23. Si realizza tale algoritmo utilizzando una struttura di condizioni annidate che va a confrontare i valori interi dei contatori e ad agire su di essi tramite altri metodi definiti in Counter secondo le necessità del nostro caso. Deve essere chiaramente possibile poter conoscere l’orario dando varie possibilità: fornire solo il conteggio delle ore, quello dei minuti totali, dei secondi totali, o semplicemente una notazione estesa dell’orario che si presenta nella forma convenzionale hh:mm:ss. Il servizio che restituisce i minuti totali dovrà comprendere un piccolo algoritmo che sia in grado di convertire le ore in minuti per poi sommarle ai minuti già presenti sul Counter minute.

Analogamente il metodo per la stampa dei secondi totali dovrà contenere un algoritmo che è simile a quello sopracitato, ma che definisce la conversione di ore e minuti in secondi per poi sommarli ai secondi già presenti. L’altro servizio di base che deve fornire questo orologio è la possibilità di dare un output contenente l’ora estesa. Questo è possibile mediante un metodo che con delle condizioni annidate verifica il “formato delle grandezze” e nel caso siano < 10 le pone nella forma 0n.

Anche in questi casi per confrontare i valori dei minuti, secondi, ore, per renderli disponibili si utilizzeranno i metodi precedentemente definiti nella classe Counter. Altri servizi aggiuntivi possono essere forniti quali quelli per rendere possibile il confronto fra due orologi, in particolare può risultare utile la definizione di metodi per interrogare un Orologio sulla uguaglianza o meno rispetto ad un altro, ma anche sapere se esso è o maggiore o minore sempre però riferito ad un secondo oggetto di classe Orologio.


ElencoRilevamenti.

Per quanto riguarda la modellazione del tipo di dato astratto Rilevamento, si può dire che sicuramente anch’esso è un oggetto composto; esattamente da un intero che rappresenta una temperatura e un orario che indica il momento in cui è stata effettuata la rilevazione. Bisogna specificare che pero nell’arco della giornata possono essere fatte più rilevazioni in diversi orari e quindi con diverse temperature. Bisogna dunque fare per forza ricorso agli array. In generale quindi un elenco di rilevamenti sarà un array di singole rilevazioni effettuate in momenti diversi della stessa giornata. Bisognerà definire un costruttore che accetta un parametro il quale indica il numero di rilevamenti effettuati nell’arco della giornata, in modo che java possa allocare poi nella memoria lo spazio sufficiente per la creazione successiva degli oggetti interessati diversi da tipi primitivi. Infatti per quanto riguarda l’array delle temperature sarà poi necessario solamente assegnare ad ogni posizione dell’array una variabile intera pronta per l’uso, mentre nel caso dell’array degli orari sarà poi necessario creare nuovi oggetti del tipo orologio. I metodi da definire che sono sicuramente indispensabili: uno che mi dia la visione d’insieme dei rilevamenti effettuati e uno che sia in grado di calcolare la media delle temperature rilevate. Inoltre può essere interessante definire un metodo che dia la possibilità di settare uno specificato rilevamento dando la posizione del rilevamento indicata con un numero intero da 1 a 10, un intero che rappresenta la temperatura in gradi centigradi e un altro intero che rappresenta l’ora del rilevamento.


Componente software.


Questo tipo di dato astratto analizzato deve essere poi sfruttato da un componente software che definisce un main il quale deve , nel caso specifico creare un elenco di 10 rilevamenti e di stampare la media delle temperature a video. Si dovrà creare un elenco di rilevamenti sfruttando il costruttore di ElencoRilevamenti e inserendo il parametro desiderato dopodiché una volta create le rilevazioni si può effettuare la media invocando il metodo definito dalla classe che sfrutta il main. In particolare si illustra un caso particolare di funzionamento.
Progetto:
Orologio.

La classe Orologio è pubblica è al suo interno definisce 4 tipi differenti di costruttori, per realizzarli si è ricorso ad un overloading del costruttore Orologio. Prima di fare questo però dichiara che vi sono tre dati di tipo counter al suo interno. Orologio(), senza alcun parametro crea al suo interno 3 oggetti di tipo Counter hour, minute, second, tutti con valore iniziale 0. Orologio(int h), crea un orologio che ha come ora iniziale quella impostata col parametro intero h che va ad agire sul costruttore del Counter hour corrispondente. Analogamente Orologio(int h , int m), va ad inizializzare hour e minute a certi valori di partenza rappresentati dagli interi h e m.

È chiaro quindi quale effetto produce il costruttore Orologio(int h , int m , int s), inizializza tutti e tre i campi dell’Orologio. Il metodo tic(), anch’esso pubblico della classe Orologio, è quello che rappresenta la lancetta dei secondi che si muove, e di tipo void perché non restituisce alcun valore, naturalmente anche lo spazio riservato ad eventuali parametri rimane vuoto perché nel nostro caso non ha senso far cambiare comportamento alla lancetta. Altro metodo pubblico presente è getHour() di tipo intero, senza alcun parametro è definito in modo da poter fornire ad un cliente la possibilità di conoscere lo stato attuale delle ore quindi del contatore di ore, Counter hour tramite una getValue() che restituisce un intero.

Il metodo public getMinute() che restituisce un intero, fornisce all’utente il conteggio totale de minuti, quindi un intero: agisce sui valori restituiti dai contatori hour e minute tramite un breve algoritmo calcola quindi il totale al momento dell’invocazione. getSecond() metodo public restituisce il conteggio totale dei secondi, un double, anche questo metodo presenta un algoritmo di semplice comprensione per il calcolo dei secondi totali.

/**Altro metodo definito da Orologio è getTime() public di tipo String restituisce l’orario esteso nel formato convenzionale hh:mm:ss; per rendere possibile questo servizio al suo interno rappresenta un algoritmo che svolge dei controlli, tramite condizioni if (Then) else, sui valori restituiti dai contatori di ore minuti e secondi e nel caso siano < 10 li pone nella forma “0”+nomeCounter.getValue() sfruttando l’ausilio di una variabile string di appoggio: time.

Metodi aggiuntivi sono tre metodi per il confronto fra due orologi, metodi pubblici di tipo boolean.

equalsTo (Orologio clock): permette di stabilire se un Orologio è “uguale” ad un altro passato come parametro. Di fatto cosa fa: converte l’orario del primo Orologio in secondi e lo confronta col calcolo totale dei secondi del secondo e verifica che siano uguali. Analogamente per i metodi per stabilire se un orologio è maggiore o minore rispetto ad un altro indicato come parametro, rispettivamente Great( Orologio clock); Small(Orologio clock). Chiaro che nell’algoritmo di riconoscimento dei secondi vi sarà una volta il segno > e l’altra il segno <.

ElencoRilevamenti.


Per quanto riguarda la classe ElencoRilevamenti pubblica dichiara di contenere al suo interno una variabile di tipo Orologio di nome timer. Il costruttore, in questo caso l’unico, ElencoRilevamenti(int n), con un parametro intero che definisce la dimensione dei due array, quello di interi che rappresentano le temperature e quello di orologi rispettivamente temp e timer.

Il metodo getR() public è di tipo void e stampa la lista dei rilevamenti effettuati, eseguendo un ciclo controllato e andando a valutare volta per volta gli elementi degli array.

Altro metodo, questa volta di tipo void, Media(), restituisce la temperatura media calcolata su n rilevamenti effettuati. I metodo void pubblico che permette di settare un singolo rilevamento ha segnature setR(int posizione, int c, int h) che rispettivamente indicano la posizione in cui il rilevamento verrà posizionato, il valore della temperatura e l’ora della giornata (solo ora es: 13 .14 ecc.).
Il componente software.

È la classe eseguibile , la parte statica del programma.

In primo luogo dopo aver definito due riferimenti ad Orologio, si creano successiavemente due orologi: rolex, swatch. Dopodiché opera su di essi e ne farà dei confronti. Successivamente viene creato l’oggetto maggio di tipo ElencoRilevamenti ( anch’esso dopo averlo riferito a quest’ultima classe). Vengono introdotti poi dei rilevamenti e calcolata la media su di essi.


Implementazione:


  • classe Counter (già vista): file Counter.java allegato;

  • classe Orologio: file Orologio.java allegato;

  • classe ElencoRilevamenti: file ElencoRilevamenti.java allegato;

  • componente software: Esp2.java allegato.


Orologio.

Nella classe Orologio all’atto della creazione di contatori hour, minute, second, si fa uso del costrutto linguistico new nel seguente modo: nome oggetto new = classe oggetto(eventuali parametri per i costruttori). Il metodo tic() tramite le condizioni annidate e l’utilizzo dei metodi di Counter, getValue(), reset(),inc() agisce secondo le necessità del caso. getHour() fa semplicemente una una getValue() del contatore hour. getMinute() utilizza l’intero min per depositare il valore dei minuti totali calcolati tramite l’espressione : (hour.getValue()*60)+minute.getValue(). Stesso comportamento ha getSecond() che deposita in un double di nome sec il valore totale di secondi calcolati tramite l’espressione: (hour.getValue()*3600)+(minute.getValue()*60)+second.getValue(). /**GetTime() se è vera questa condizione: (hour.getValue() < 10 && minute.getValue() < 10 && second.getValue() < 10), stampa su video prima di ogni valore il carattere “0”e tra i valori dei contatori “:” in modo da ottenere il formato hh:mm:ss. Gli altri controlli che è necessario fare sono le altre permutazioni possibili : ("0" + hour.getValue() + " : " + "0" + minute.getValue() + " : " + second.getValue() + "\n"), se ore e minuti sono minori di 10. ("0" + hour.getValue() + " : " + minute.getValue() + " : " + "0" + second.getValue() + "\n") se ore e secondi sono minori di 10. (hour.getValue () + " : " + "0" + minute.getValue() + " : " + "0" + second.getValue() + "\n") se minuti e secondi sono minori di 10. e così via facendo tutte le verifiche possibili. */

I metodi per il confronto di orologi, che restituiscono un dato di tipo boolean si basano sul fatto che prima di essere confrontato con un altro il primo orario deve essere convertito in secondi totali e poi si va a vedere se i secondi totali dei due orologi corrispondono (metodo equalsTo(Orologio clock)), oppure il primo è < o >del secondo.

boolean b = (((hour.getValue()*3600)+(minute.getValue()*60)+second.getValue())== clock.getSecond()). Sostiuendo == con < e > si realizzano rispettivamente i metodi GreatTo(Orologio clock) e SmallTo(Orologio clock).


ElencoRilevamenti


Nella classe ElencoRilevamenti il costrutto linguistico [] sta ad indicare che il tipo di dato è un array. int [] temp, Orologio [] timer, sono due riferimenti, uno ad un array temp di tipo interi, l’altro ad un array di oggetti di classe Orologio. Successivamente questi oggetti vengono creati tramite il costrutto linguistico new. Notare l’uso del costruttore ElencoRilevamenti(int n), dove n intero permette di comunicare alla new la dimensione degli array da costruire:

timer = new Orologio [n].

il metodo public getR() di tipo void restituisce a video l’elenco dei rilevamenti e lo fa tramite un ciclo di for che incrementando la variabile di appoggio c inizializzata a 0 permette di stampare n ( dimensione dei 2 array) rilevamenti.

Il metodo public Media() è di tipo void. Nel caso volessimo l’approssimazione ad un valore intero basta dichiarare il metodo intero. Una volta creato effettivamente un elenco di rilevamenti è possibile tramite setR(int posizione, int c, int h) creare un singolo rilevamento andando ad agire sui singoli campi dei 2 array: temp[posizione] = timer[posizione] = new Orologio(h).


Il componente software.

Sfrutta semplicemente i metodi definiti dalle altre due classi.



Test: schermata dal prompt di dos prelevata con selezione e copia incolla.
C:\java2\esp2>java Esp2
hour : 10

minute : 620

second : 37230.0

second : 37230.0

are equal? true

second : 37231.0

second : 37230.0

are greater than 2th Orologio? true
il rilevamento 0 : 8
il rilevamento 1 : 10
il rilevamento 2 : 14
il rilevamento 3 : 0
il rilevamento 4 : 0
il rilevamento 5 : 0
il rilevamento 6 : 0
il rilevamento 7 : 0
il rilevamento 8 : 0
il rilevamento 9 : 0
il rilevamento 0 : 8
il rilevamento 1 : 10
il rilevamento 2 : 14
il rilevamento 3 : 19
il rilevamento 4 : 24
il rilevamento 5 : 22
il rilevamento 6 : 18
il rilevamento 7 : 16
il rilevamento 8 : 14
il rilevamento 9 : 10

the average temperature 15.0 C degrees
the exact time

10:20:33

Concetti:
Una possibilità in java che risulta fondamentale è quella di poter utilizzare in tutte le classi possibili ed immaginabili classi già definite, o dallo standard o da noi stessi. In particolare in questa esperienza questo tema è emerso dalla esigenza di creare un oggetto composto, o meglio una classe composta che contiene al suo interno riferimenti ad altre classi. L’Orologio in realtà non è altro che un insieme di Counter collegati tra di loro e opportunamente sincronizzati.

La classe che “contiene” i riferimenti ad altre classi può accedere solamente ai dati e ai metodi pubblici di queste ultime. Così la Classe Orologio può adoperare tutti i metodi già definiti in Counter ma non può accedere al dato privato value che è l’intero che rappresenta il valore del contatore.

In java bisogna prima creare un riferimento ad oggetto e poi creare l’oggetto desiderato.

Nella costruzione degli oggetti composti è prima necessario specificare i riferimenti presenti alle classi che verrano usate (es : Counter, hour, minute, second ), poi all’interno del costruttore gli oggetti dovranno essere creati tramite il costrutto new. È chiaro che all’atto della creazione qual’ora il costruttore invocato abbia più liste di parametri e possibile utilizzare quella che realmente interessa. (es: public Orologio(int h){ hour = new Orologio(h); .........}).

Tutti i metodi poi definiti dalla classe composta posssono utilizzare a loro volta metodi e dati

(publici) definiti dalle classi che componenti. Quando nel nostro caso creiamo un oggetto di tipo Orologio, è poi il costruttore in esso definito che si preoccupa di creare gli oggetti di tipo Counter che lo compongono. Bisogna fare attenzione alle parentesi {} quando si vanno a definire costruttori e metodi, possono creare dei problemi soprattutto su il codice è consistente, una buona abitudine sarebbe di aprire e chiudere subito le parentesi e poi andare a scrivere all’interno il corpo della funzione.


Anche la classe ElencoRilevamenti è un oggetto composto, in questo caso però entrambi gli oggetti composti sono degli array. Gli array sono oggetti identificati dal costrutto linguistico []. Come ogni oggetto è necessario prima definire un riferimento e poi attuare la creazione. All’atto del riferimento (es: int temp[]; Orologio timer[];) , vengono creati in memoria gli spazi che servono per i riferimenti. Non è necessario infatti specificare la dimensione dell’array che verrà poi specificata all’atto della creazione degli oggetti e rimarrà fissa. Il linguaggio richiede la creazione nel modo gia visto in più nelle parentesi quadre va specificata la dimensione degli array.

(timer = new Orologio [n]; ) Questa operazione crea in memoria lo spazio sufficiente per l’array di dimensione specificata. Per poter accedere alle varie posizioni dell’array si utilizza la notazione come in C , varibile[posizione] = dato; nel caso che il dato in questione sia di tipo primitivo. ( si nota nel metodo setR();). Se si vuole accedere ad una posizione di un array di dato non primitivo è necessario creare all’interno della posizione voluto un nuovo riferimento all’oggetto voluto nel nostro caso un riferimento ad Orologio. (timer[posizione] = new Orologio(h);).


Condividi con i tuoi amici:


©astratto.info 2019
invia messaggio

    Pagina principale