Linguaggi di Programmazione: Paradigmi di Programmazione (Sperimentazioni)
Corso di Laurea in Informatica
a.a. 2000/2001
Prof. Alberto Martelli
Dr. Matteo Baldoni
Ultimo aggiornamento in data --->
Sessione d'esame: l'esame di Sperimentazione di
Linguaggi di Programmazione: Paradigmi di Programmazione per la
sessione marzo-aprile si terrà il giorno 21
marzo 2002 alle ore 14:00, laboratorio "unix".
E` necessario prenotarsi on-line
per sostenere l'esame.
Attenzione!!
L'appello d'esame del 21 marzo 2002 sarà
l'ultimo valido con il presente laboratorio.
Dalla sessione successiva si dovrà sostenere l'esame con il laboratorio
che verrà presentato durante il corso di
Sperimentazioni
di Linguaggi di Programmazione: Paradigmi di Programmazione
dell'anno accademico 2001-2002.
ATTENZIONE!! Modifica del testo di laboratorio per
chi intendeere l'esame a partire da settembre.
IMPORTANTE:
il testo del laboratorio verra` spesso aggiornato, sia per
l'aggiunta delle parti ancora mancanti sia come conseguenza
delle note e commenti emersi durante le lezioni.
Le parti nuove, le note ed i commenti piu` recenti verranno indicate dal
seguente simbolo: .
Laboratorio
Si ricorda che per poter svolgere il laboratorio e` necessario prima di tutto
iscriversi compilando l'apposito
form
nel quale vanno indicati i componenti del gruppo, che possono essere al piu` due,
e i loro numeri di matricola.
Alla consegna del laboratorio e` necessario allegare:
-
un floppy disk contenente il codice sorgente e compilato del progetto svolto con tutte le
istruzioni necessarie ad un facile utilizzo del software prodotto
-
il listato del codice sorgente
-
la documentazione generata mediante javadoc
-
i diagrammi di classe UML ed una relazione sul lavoro svolto
Maggiori dettagli verranno forniti nella sezione
modalita` d'esame il
piu` presto possibile.
Parte Prima
Si definisca una classe Banca ed una classe ContoCorrente rappresentante,
rispettivamente, una banca ed un conto corrente in una banca.
Le informazioni (campi) da rappresentare (sceglierne la visibilita`, il tipo,
se statico oppure no, la classe di appartenenza) sono le seguenti:
- totaleSoldibanca, che tiene il totale dei soldi della banca;
- tassoStandard e tassoPassivoStandard che tengono i rispettivi
tassi annuali d'interesse, e che sono gli stessi per tutti i conti;
- maxScopertoStandard, che rappresenta il massimo saldo negativo
ammissibile su un conto, e che e` lo stesso per tutti i conti;
- numerazioneConti, che tiene l'ultimo numero di conto attribuito;
- numeroConto, che contiene il numero di un conto corrente;
- giornoUltimoInteresse, che memorizza il giorno in cui e` stato
attribuito ad un conto l'ultimo interesse;
- nome, che contiene il nome del proprietario di un conto;
- password, che contiene un codice alfanumerico di accesso al conto;
- interesseMaturato, che tiene l'interesse maturato ma non ancora accreditato
o addebitato.
- forfaitSpese, che contiene il costo forfettario applicate ad
un conto corrente, ad esempio 30 euro;
- nomeBanca, che contiene il nome della banca.
La classe ContoCorrente deve contenere almeno due
costruttori:
- ContoCorrente(nome), che permette di creare un conto per un
dato nome, con saldo iniziale zero, e con numero assegnato automaticamente
in base a numerazioneConti;
- ContoCorrente(nome, saldoIniziale), che permette di creare
un conto come sopra, ma con un saldo iniziale (e conseguente aggiornamento
del totaleSoldiBanca).
La classe Banca deve contenere almeno un costruttore:
- Banca(nome, capitaleSociale), che permette di creare una
banca con un capitale iniziale (totaleSoldiBanca) dato.
Si definiscano inoltre i seguenti metodi (sceglierne la classe di
appartenenza, la visibilita`, il tipo dell'eventuale valore/oggetto restituito,
il tipo degli eventuali parametri):
- incrementaGiorno(), che incrementa contatoreGiorni di uno;
- incrementaSettimana(), che incrementa contatoreGiorni di 7 giorni;
- incrementaMese(), che incrementa contatoreGiorni di 30 giorni;
- incrementaAnno(), che incrementa contatoreGiorni di 360 giorni;
- cambiaTassoStandard(nuovoTasso); che cambia il tasso di interesse attivo;
- cambiaTassoPassivoStandard(nuovoTasso), che cambia il tasso di interesse passivo;
- getTotaleSoldiBanca(), che restituisce il totale dei soldi della banca;
- getSaldo(), che restituisce il saldo di un conto corrente;
- getInteresseMaturato(), che restituisce l'interesse maturato;
- deposita(valore), il quale controlla che valore sia positivo, poi aggiorna
interesseMaturato in base al saldo precedente, ed effettua il deposito (cioe`
aggiorna il saldo, ecc.); se valore e` negativo non effettua alcuna operazione
ma viene sollevata un'opportuna eccezione di tipo
MovimentoErrato (che va opportunamente definito);
- preleva(valore), come il precedente, per il prelievo; oltre al controllo che valore
sia positivo, effettua anche il controllo che se il saldo diventa negativo, il passivo
non superi il massimo scoperto ammesso, e inoltre che la banca abbia abbastanza soldi,
in modo che totaliSoldiBanca non sia mai negativo (mentre il saldo del singolo conto
puo` esserlo); se valore e` negativo non effettua alcuna operazione ma
viene sollevata un'opportuna eccezione di tipo MovimentoErrato;
- trasferisci(valore, altroContoCorrente), il quale trasferisce una somma
(valore) di denaro da un conto ad un altro della stessa banca;
- bonifico(valore, altraBanca, altroContoCorrente), il quale trasferisce una somma
(valore) di denaro da un conto ad un altro appartenente ad un'altra banca;
- calcoloSaldoFinale(), che accredita o addebita sul conto l'interesse maturato fino a quel
momento ed addebiti le spese forfettarie.
Si ridifinisca, inoltre, il metodo toString() per la classe ContoCorrente
per visualizzare lo stato di un conto in maniera opportuna.
Ogni banca memorizza in un array di tipo ContoCorrente[]
i conti correnti presenti in essa e fornisce i metodi per creare
(e quindi inserire nel suddetto array) conti correnti,
secondo le modalita` descritte per i costruttori di ContoCorrente,
e per ricercare un conto dato il numero di conto numero.
Si definisca un metodo che effettui il calcolo del saldo finale
su ognuno dei conti presenti in una banca.
Si definisca poi, in una classe ProvaBanca, un metodo main che
effettui il test delle classi precedentemente definite,
creando una banca, dei conti in tale banca ed effettuando
varie operazioni su tali conti e simulando il trascorrere del tempo.
Parte SecondaContoCorrenteConSpese sottoclasse di
ContoCorrente, in cui vi siano:
- tre costanti, numOperazioniGratis, costoOperazione
e maxScoperto, inizializzate opportunamente;
- un campo (privato? pubblico?) di istanza numOperazioni,
inizializzato a zero;
- la ridefinizione dei metodi preleva e deposito in modo
che numOperazioni venga incrementato ogni volta che si fa un prelievo o
un deposito su quel conto;
- un metodo addebitaSpese() il quale addebita sul conto il costo delle
operazioni eccedenti il numero di operazioni gratis ed azzeri numOperazioni;
- la ridefinizione del metodo calcolaSaldoFinale() in modo che esso,
invece di addebitare le spese forfettarie, invochi il metodo addebitaSpese().
Si modifichi opportunamente il metodo main della classe
ProvaBanca usata precedentemente per testare anche
i conti correnti con spese.
Parte Terza
Si definisca un'interfaccia Comparabile che specifichi i tre
metodi seguenti:
- un metodo boolean maggiore(Comparabile ob), le cui implementazioni
si intende confrontino con this l'oggetto confrontabile
ob restituendo true o false
a seconda che this sia o non sia maggiore di ob, oppure generando un'eccezione
(di tipo ClassCastException) se il confronto non e` possibile;
- un metodo boolean uguale(Comparabile ob), inteso come analogo al precedente;
- un metodo int compara(Comparabile ob), le cui implementazioni sono intese
restituire -1, 0 o +1 a seconda che this sia minore, uguale o maggiore di
ob, oppure generi un'eccezione (di tipo ClassCastException).
Si modifichi poi la definizione della classe ContoCorrente degli esercizi
precedenti in modo che essa implementi l'interfaccia Comparabile, ad esempio
confrontando rispetto al valore del saldo, oppure rispetto al nome dell'intestatario.
Si definisca in una nuova classe (ad esempio sortArrays) un semplice metodo di ordinamento
void sort(Comparabile[]) (statico?), e lo si applichi all'array di conti
di una banca.
Si modifichi la definizione della classe Banca in modo che anch'essa implementi
l'interfaccia Comparabile, ad esempio confrontando rispetto al totaleSoldiBanca
e si applichi il metodo di ordinamento sort anche ad un array di bance opportunamente
creato.
Si esegua nuovamente il presente esercizio utilizzando l'interfaccia Comparable
e la classe java.util.Arrays fornite con il Development Kit di Java al posto
dell'interfaccia Comparabile e della classe SortArray precedentemente usate.
Parte Quarta
Definire una classe LogBanca che implementando la classe java.util.Observer
permetta di memorizzare su di un file di log tutti i movimenti effettuati sui conti correnti
delle varie banche presenti in una simulazione secondo il seguente schema:
nome banca |
codice ABI banca |
numero_conto |
movimeneto |
data |
importo
A tal fine si modifichi la classe ContoCorrente (e ContoCorrenteConSpese?)
in modo che questa estenda la classe java.util.Observable e ad ogni operazione
di creazione di un conto, prelievo e deposito (e trasferimento?)
generino un evento ascoltato da un opportuno
Observer (un'istanza della classe LogBanche).
Si noti che il file di log e` unico per tutte le banche.
Si modifichi la classe Banca introducendo un metodo che permetta ad
una sua istanza di analizzare il proprio file di log
effettuando delle statichiche sui movimenti memorizzati (ad es. numero di operazioni
effettuate, totale somme versate, totale somme prelevate, ecc.) e le visualizzi
su video.
Si aggiunga ancora allla classe Banca una coppia di metodi che
permettano di salvare su di un file lo stato della banca
stessa e ripristinarlo in un secondo momento.
A tale scopo si utilizzi la possibilita` di salvare oggetti su file (Serializable Object).
Modificare la classe ProvaBanca in modo da testare le modifiche apportate in questa
quarta parte del laboratorio.
Parte Quinta
Si realizzi una interfaccia grafica simile a quella sullo
stile di questa figura
che utilizzi le principali operazioni realizzate
nelle precedenti parti del laboratorio.
Si noti la presenza di una JTextArea che riporta le informazioni
sulle operazioni effettuate nei conti correnti delle
varie banche presenti nella simulazione in modo analogo
a quanto fatto nella quarta parte del laboratorio.
IMPORTANTE:
non e` permesso l'utilizzo di nessuno strumento di programmazione
visuale (es. JBuilder) per la realizzazione dell'interfaccia grafica.
Questi possono eseere usati solo come editor.
Parte Sesta
Utilizzando la tecnologia RMI permettere ad una applicazione
esterna di accedere ad una o piu` banche per l'operazione di
trasferimento (a favore).
Ad esempio, si supponga di voler trasferire una somma di
denaro s da un conto c1 presso la banca b1 al conto c2
presso la banca b2 allora la banca b2 potra` essere una
banca remota (quindi solo trasferimenti a favore di banche remote).
Per realizzare questo si puo` pensare di utilizzare l'applicativo
che si sta realizzando sia come client che come server, il primo
accede a banche rese remote dalla seconda.
Si decida, quindi, quali metodi e` necessario rendere utilizzabili
remotamente dai client (guardare a come si e` realizzato il
metodo trasferimento e quindi quali metodi si invocano sulla banca
proprietaria del conto che riceve il trasferimento di denaro
per decidere).
Quindi il main del client (il main
della classe ProvaBanca del client)
dovra` invocare Naming.lookup per reperire i riferimenti agli
oggetti di tipo Banca remoti (e resi disponibili
mediante Naming.rebind)
nel metodo main del server (il main
della classe PorvaBanca del server).
Non e` necessario che si faccia uso dell'interfaccia grafica.
Parte Settima: prelievi, trasferimenti e bonifici periodici
Si estenda il laboratorio
introducendo la possibilità di
definire dei prelievi, trasferimenti e bonifici periodici su di un conto corrente
(ad esempio, "ogni g giorni").
A tale fine si realizzi una classe ContoCorrenteTrigger
il cui costruttore permetta di specificare il tipo di
movimento periodico da effettuare e le informazioni necessarie
per eseguirlo (esempio: conto corrente sorgente, conto corrente destinatario,
importo).
Per realizzare questa parte ci si può ispirare alla
quarta parte. Una semplice soluzione potrebbe essere quella
di definire gli oggetti di tipo Banca osservatori di un
oggetto di tipo Data che registra lo scorrere del tempo.
Ogni incremento del tempo farebbe generare un evento
che costringerebbe gli oggetti di tipo Banca a verificare
se vi sono dei movimenti periodici da applicare,
in maniera del tutto simile a quanto viene fatto
per la registrazione dei file di log.
Una banca dovrebbe quindi memorizzare una lista
dei vari movimenti periodici (oggetti di tipo ContoCorrenteTrigger)
eseguendo i movimenti applicabili ad ogni notifica di incremento
del tempo.
Si noti che si deve provvedere la possibilità di
aggiungere ed eliminare in qualsiasi momento tali
movimenti periodici.
Note e Commenti
-
Durante un'esecuzione e` possibile avere piu` istanze della classe Banca.
Ogni banca avra` i propri conti correnti. L'operazione di bonifico e`
analoga a quella di trasferimento ma coinvolge conti correnti di
due banche diverse.
-
Le operazioni di creazione, deposito, prelievo, trasferimento, bonifico
dovrebbero avvenire per mezzo di una banca come nella realta`.
Quindi queste operazioni dovrebbero essere richiamabili attraverso
opportuni metodi della classe Banca anziche` usati direttamente.
Ad esempio la classe Banca potrebbe contenere un metodo
prelevaDaConto(contoCorrente,valore) che invoca il metodo
preleva(valore) sul conto contoCorrente.
Fare pero` attenzione a cosa e` contoCorrente, probabilmente
questo e` individuato mediante nome e NumeroConto
come avviene nella realta`. Si dovra` effettuare un controllo dell'effettiva
esistenza del conto presso la banca di appoggio (scansione dell'array?)
e quindi effettuare l'operazione o sollevare un'eccezione se il conto non esiste.
-
Per creare il file di log nella maniera piu` agevole
si faccia uso della possibilita` di passare un oggetto come argomento extra
del metodo notifyObserver. Forse, l'idea migliore e` quella di
passare come argomento il puntatore al conto stesso e quindi estrarre da
esso, con opportuni metodi, le informazioni desiderate. Questo garantira`
maggiore flessibilita` se desiderassimo cambiare l'output nel file di log.
-
I costruttori indicati nella parte prima dell'esercitazione sono "indicativi",
variazioni di questi sono sicuramente possibili. Questi sono fortemente
dipendenti dalle scelte che si effettuano su come rappresentare le infomazioni
indicate inizialmente.
-
Sarebbe bene che il tempo trascorresse uguale per tutte le banche ed ogni
ogni banca avesse una propria data di fondazione.
-
Per simulare il trascorrere del tempo e` sufficiente invocare direttamente
nel metodo main della classe ProvaBanca i
metodi incrementaGiorno(), incrementaSettimana(), incrementaMese(),
incrementaAnno().
-
Per la definizione della password nella prima parte del laboratorio c'e`
la massima liberta` di interpretazione. E` possibile introdurla direttamente
nel costruttore, generarla automaticamente o impostarla successivamente
mediante un apposito metodo.
-
Ogni conto corrente dovrebbe sapere a che banca appartiene. Questo significa
che i costruttori per creare dei conti correnti potrebbero contenere tra i
parametri la banca di appartenenza. Alternativamente
si puo` immaginare che sia presente nella classe ContoCorrente
un metodo apposito per inizializzare tale informazione successivamente.
Ovviamente tutto questo se questa informazione viene ritenuta utile.
-
Le operazioni da effettuare sui conti correnti, contenute nel metodo
nel main della classe ProvaBanca puo` anche essere
specificate da tastiera (in questo caso e` possibile utilizzare le classi
fornite insieme al libro Java 2: i fondamenti) ma non e` richiesto
dall'esercitazione.
-
E` possibile utilizzare altre strutture dati al posto dell'array di
tipo ContoCorrente[] indicato nella parte prima del laboratorio.
E` possibile utilizzare, ad esempio, Vector, List, Map definite
nel nel package java.util.
-
La formula per calcolare gli interessi e`: I = C * r * t / 36500, dove
I e` l'interesse maturato, C il capitale, r il tasso applicato,
t il tempo (espresso in giorni).
-
Come calcolare gli interessi?
Un modo realistico e nello stesso tempo semplice puo` essere il seguente.
Sia t1 il giorno dell'ultimo movimento effettuato (informazione
memorizzata nel campo giornoUltimoInteresse)
in un determinato conto corrente che lo ha portato ad avere un saldo S1
e si supponga di effettuare il giorno t2 (con t1 <= t2)
una operazione che modifica il saldo S1 nel saldo S2.
Sia r il tasso di riferimento e si supponga che im sia l'interesse
maturato, e non ancora accredita, da quel conto
(infomazione memorizzata nel campo interesseMaturato).
Allora si dovra` calcolare l'interesse maturato I1 tra il tempo t1
e il tempo t2 per il capitale S1 (I1 = S1 * r * (t2 - t1) / 35600) e quindi
sommarlo all'interesse maturato sino a quel momento im (im = im + I1).
A questo punto ci si ricorda che il giorno dell'ultimo movimento non e` piu`
t1 ma t2 (giornoUltimoInteresse = t2).
Quando si invochera` il metodo calcolaSaldoFinale() su quel conto
il saldo verra` aggiornato con il contenuto del campo interesseMaturato,
impostando nuovamente a zero il valore di quest'ultimo.
-
Il campo totaleSoldiBanca e` da intendere come il totale dei
depositi bancari sommato al capitale iniziale della banca.
-
Nei diagrammi di classe un campo o un metodo static sono
indicati sottolineandone il nome.
-
E` utile ridefinire nelle classi Banca, ContoCorrente e ContoCorrenteConSpese
il metodo public String toString() della classe Object. In questo modo
effettuare delle stampe dei valori dei vari oggetti risultera` molto semplice.
Infatti si ricorda che il metodo println() della classe PrintStream, se
utilizzato passando un oggetto, invoca automaticamente il metodo toString()
nella classe Object per la conversione in un oggetto di tipo String.
Quindi, poiche` ogni classe e` sottoclasse di Object,
se il metodo toString() viene ridefinito allora per binding dinamico
verra` utilizzato il metodo specificato nella sottoclasse.
Ad esempio, se b e` un oggetto di tipo Banca e nella classe Banca e`
ridefinito il metodo toString() allora posso utilizzare
System.out.println(b) ottenendo la stampa da me desiderata (e definita
nel metodo toString() stesso).
-
Si noti che quando si calcola il saldo finale si devono considerare
gli interessi maturati dall'ultima operazione effettuata sul conto.
Ad esempio, se in un certo conto corrente l'ultima operazione
effettuata risale al girono t1 e il calcolo del saldo finale
e` effettuato il giorno t2, con t1 <= t2, allora vanno calcolati anche
gli interessi passivi o attivi (a seconda che il saldo sia passivo
o attivo al tempo t1) per il periodo da t1 a t2.
-
Fare attenzione nella terza parte del laboratorio alla frase
"... oppure generando un'eccezione se il confronto non e` possibile ...",
la questione e` relativa al fatto che quando si implementa il metodo
boolean maggiore(Comparabile ob) (ed analogamente uguale e compara)
e` necessario effettuare un downcast del parametro ob per poterlo
utilizzare come oggetto di tipo ContoCorrente (ad esempio
per richiederne il saldo) ma non vi e` garanzia che lo sia.
Questo potrebbe sollevare un'eccezione di tipo ClassCastException.
Si noti che poiche` ContoCorrente dovra` implementare
l'interfaccia Comparabile allora ContoCorrente e` un sottotipo
(e` una sottoclasse) di Comparabile.
-
Si noti che quando si implementa un'interfaccia
ogni metodo deve essere definito pubblico anche se
nell'interfaccia non era specificato che il metodo lo era.
Infatti ogni metodo di un'interfaccia e` implicitamente definito
pubblico. L'errore che spesso si incontra in questo caso e` del tipo:
"The method ... declared in class .. cannot override the method of the
same signature declared in interface ... . The access modifier is
made more restrictive".
-
Nella quarta parte del laboratorio si richiede di registrare
in un file di log tutte le operazioni eseguite nel vari conti
creando un opportuno evento quando un conto e` modificato.
Chi lo desidera, invece di far generare l'evento da un oggetto
di tipo ContoCorrente, puo` farlo generare da un oggetto di tipo
Banca visto che ogni operazione sul di un conto passa attraverso
l'invocazione di un metodo su di una banca.
Fare attenzione che in questo caso e` necessario gestire
anche le operazioni di trasferimento e bonifico in quanto nella
proposta originale sono gestiti in modo automatico dalla
combinazione di prelievo e deposito.
-
Chi avesse utilizzato una struttura dati diversa dall'array per memorizzare
i conti correnti di una banca nella prima e seconda parte dovra` adeguare
di conseguenza la terza parte del laboratorio. Ad esempio, se la struttura
dati scelta e` l'ArrayList allora la classe sortArrays
(rinominata sortArrayList?) dovra` definire un metodo di ordinamento
che ha come parametro un ArrayList anziche` Comparabile[].
In questo caso sara` pero` necessario effettuare un downcast all'interno
della procedura sortArrayList per poter utilizzare i metodi di confronto
in ContoCorrente (downcast a Comparabile? ContoCorrente?
Banca?).
Nella terza parte del laboratorio si richiede anche di utilizzare il package
Arrays, si noti che ArrayList dispone di analoghe funzionalita`.
-
Nella quarta parte dell'esercitazione di laboratorio e`
possibile passare le informazioni dall'oggetto di tipo
Observable all'oggetto Observer mediante il parametro
del metodo notifyObserver. Ad esempio si puo` definire
una classe EventLogBanca estensione della classe EventObject,
i cui oggetti contengono tutte le informazioni necessarie
a realizzare il file log. Per la definizione della
classe EventLogBanca si puo` fare riferimento
all'esempio Contatore D.E.M..
-
Durante l'interazione con l'interfaccia grafica non e` necessario
preoccuparsi dell'incremento del contatore dei giorni.
Si faccia conto che l'interazione avvenga tutta nello stesso giorno.
Ad esempio, si crei un certo numero di banche e conti correnti
(anche con spese) e quindi si avvii l'interfaccia grafica per
la gestione delle operazioni su di esse. Non e` necessario
che l'interfaccia grafica si preoccupi di gestire la creazione
degli oggetti di tipo Banca e ContoCorrente.
-
Supponiamo di voler definire un metodo per la memorizzazione
(ad es. salvaBaca) e il caricamento (ad es. leggiBanca)
di un oggetto di tipo Banca da un file.
Il primo potra` essere un metodo
di istanza e quindi utilizzato invocando il metodo su
di un oggetto di tipo Banca che verra` salvato su di
un file (magari specificato in un apposito parametro).
Il secondo metodo, invece, restituira` l'oggetto di tipo
Banca contenuto in un dato file specificato, supponiamo,
nuovamente mediante un parametro. A questo punto e` evidente che
il metodo leggiBanca non potra` essere un metodo di
istanza bensi` un metodo di classe (statico).
-
Per la realizazione della sesta parte i cambiamenti da apportare
alle classi dovrebbero essere i seguenti:
-
una interfaccia (es. BancaRemoteInterface) che estende la
classe java.rmi.Remote e che dichiara quali sono i metodi utilizzabili
su un oggetto remoto di tipo Banca
-
modificare la classe Banca in modo che estenda la classe
java.rmi.server.UnicastRemoteObject e che implementi l'intefaccia
definita precedentemente (BancaRemoteInterface)
-
definire una classe ProvaBancaServer che crei una o piu` oggetti
di tipo Banca da rendere disponibili remotamente mediante il metodo
java.rmi.Naming.rebind(String name, Remote obj), dove name e`
qualcosa del tipo rmi://ipaddress:port/nameobject e obj e`
l'oggetto di tipo Banca che si desidera rendere disponibile remotamente.
Si ricordi che prima di invocare questo metodo e` necessario
avviare il processo server registry mediante
java.rmi.registry.LocateRegistry.createRegistry(port)
oppure avviandolo da linea di comando tramite il comando rmiregistry port
(ipaddress e port sono rispettivamente l'IP della macchina su cui risiede
il server e il numero di porta scelta)
-
definire una classe ProvaBancaClient che utilizzi gli oggetti
di tipo Banca locali e remoti. Gli oggetti remoti devono essere
resi disponibili nell'applicativo client mediante l'invocazione
del metodo java.rmi.Naming.lookup(String name), dove name e`
la stringa definita nel punto precedente usato nel seguente modo
BancaRemoteInterface bancaremota =
(BancaRemoteInterface)Naming.lookup("rmi://ipaddress:port/nameobject");
E` importante notare l'uso di BancaRemoteInterface anziche` Banca.
Si noti che potrebbe essere necessario apportare qualche altra modifica
in quanto gli oggetti remoti presso il client sono necessariamente di tipo
BancaRemoteInterface, una sopraclasse di Banca. Ad esempio, se si desidera
memorizzare gli oggetti remoti nello stesso array che contiene gli oggetti
di tipo Banca locali questo non e` possibile poiche` implicherebbe un
downcast da BancaremoteInterface a Banca.
Fare quindi attenzione a questi aspetti.
|