Sviluppo dell’“Enterprise”
application
Lavaza
Prima puntata
Scopo dell’applicazione
• Nel nostro dipartimento abbiamo una macchina per il caffè che utilizza
delle cialde preconfezionate. Tali cialde sono vendute in bustine che ne
contengono due al prezzo di ¤ 0.62. In genere vengono acquistati
gruppi di 5 bustine al prezzo di ¤ 3.10.
• Daniela, una delle nostre segretarie si occupa della vendita, e di
richiedere i rifornimenti quando è il momento.
• Le bustine sono fornite in scatole da 50.
• Daniela, per prevedere quando è il momento giusto di fare rifornimento,
è interessata a sapere quanti caffè ha ancora disponibili, ed a
informazioni statistiche riguardanti quanti caffè si vendono durante i vari
periodi.
• Molte volte noi acquistiamo i caffè a credito, e siamo molto smemorati.
• Quando Daniela non è presente in Dipartimento altro personale
amministrativo si occupa di venderci i caffè.
v. 3
Cosa mettere nei tre strati
Client
un solo tipo di
application client
in ogni momento
una sola istanza
sarà in
esecuzione
(sulla macchina
di Daniela o
dell’altra persona
che venderà i
caffè in sua
vece)
Business
……..
Enperprise IS
Un database
contenente le
seguenti
informazioni
• debiti (crediti ?) dei
consumatori
• numero di bustine
vendute in ogni
mese
• il numero delle
bustine disponibili
• i soldi in cassa
• quando sono stati
fatti gli ordini (??)
v. 3
Application client
• funzionalita offerte
– Registrare una vendita, classificata in a credito o in contanti
(facilitazioni per 5 bustine, una scatola)
– Mostrare quante bustine sono disponibili
– Mostrare le statistiche di vendita (bustine vendute in ogni mese)
– Controllare se un consumatore ha dei debiti
– Pagare un debito (totalemente o anche parzialmente ?)
– Mostrare quanto ci deve essere in cassa
– Registrare l’arrivo di un rifornimento di caffè
• GUI
– schemino grafico
– deve offrire mezzi per accedere alle funzionalità di cui
sopra
• descrivere operativamente le funzionalità di cui
sopra, dopo aver definito gli altri due strati
v. 3
Seconda puntata
EIS tier
• In questa applicazione lo strato EIS contiene giusto
un unico database
• Schema del data base
v. 3
Schema del database
In questo caso usiamo una notazione UML-like, self-explaining, ma è
possibile usarne altre (es. entity relationship)
<<entity>>
<<entity>>
<<entity>>
Consumer
Sell
Refill
name: String
surname: String
login: String
{quella che ogni persona
del dipartimento usa nel
suo indirizzo di email}
deb: Int
{il debito corrente}
month: Int
year: Int
quantity: Int
key: int
{= month * 37 * year * 43}
day: int
month: Int
year: Int
quantity: Int
key: int
{= day * 51 + month * 37 * year * 43}
<<entity>>
Situation
cash: Euro
{money contained in the cash}
coffee: Int
{number of packages available}
quantity: Int
key: int
{ = 1, since there will be always a
unique object of this class}
in questo caso non ci sono
relazioni tra le varie entità
v. 3
Business tier
• schema (software architecture)
– mostra quante istanze di enterprise beans ci sono e
come interagiscono tra di loro
• gli enterprise beans, opportunamente classificati,
utilizzati per questa applicazione
v. 3
Entity beans
• Lo schema del database presentato
precedentemente definisce in modo ovvio quali
saranno gli entity bean utilizzati nella nostra
applicazione: uno per ogni relazione del database
• Quale tipo di persistenza avranno?
– la persistenza gestita dal contenitore sembra
ragionevole in questo caso, pertanto scegliamo quella
v. 3
Session beans (1)
• quali/quante/di che tipo sono le sessioni interattive
dell’application client (AC da ora in poi) con lo
strato business ?
– sono possibili varie scelte
* minimale
˚ un’unica sessione che inizia quando l’AC parte e finisce
quando l’AC termina l’esecuzione
* massimale
˚ una sessione differente per gestire ogni funzionalità dell’AC
* preferita, una sessione per questi gruppi di funzionalità, che
ragionevolmente saranno eseguiti assieme
˚
˚
˚
˚
effettuare una vendita
controllare la situazione (bustine disponibili e soldi in cassa)
vedere le statistiche di vendita
gestire il debito di un consumatore (controllare quanto deve, e
magari pagare)
v.
˚ registrare l’arrivo di un rifornimento di caffè
3
Session beans (2)
<<session>>
H_Sell
<<session>>
Check
<<session>>
H_Debit
<<session>>
Statistic
<<session>>
H_Refill
Vediamo ora grossolanamente che cosa fanno
presentando possibili scenari (casi/esempi di esecuzione) delle loro
attività
per semplicità ora non consideriamo le possibili situazioni di errore
aggiungerle per esercizio
v. 3
H_Sell (gestire una vendita)
in contanti
AC
Situation
H_Sell
Sell
{quella del mese corrente}
sellMon(nPks)
sellMon(nPks)
sold(nPks)
a credito
AC
H_Sell
sellCred(lg,nPks)
Cosumer
{quella con login = lg}
Situation
Sell
{quella del mese corrente}
sellCred(nPks)
debit(nPks)
sold(nPks)
v. 3
H_Debit (gestire i debiti)
AC
H_Debit
E = debitOf(lg)
Consumer
{quella con login = lg}
E = get_deb()
return
pay(lg,E)
payed(E)
v. 3
Check (controlla situazione)
AC
Check
Situation
(E,pkg) = check()
(E,pkgs) = how()
v. 3
H_Refill (registra un rifornimento)
AC
H_Refill
Situation
arrived(nBox)
refill&Pay(nBox)
v. 3
Static (esamina le statistiche di vendita)
AC
Statistic
i  CO D(y1,y2)
{quello di codice I}
si:Sell
giveData(today,y1,y2)
qi = HowMany()
retrun (q1 :: … ::qk)
COD(y1,y2) = { 1, …, k} =
codici dei mesi tra
inizio anno y1 e
l’ultimo mese dell’anno y2
v. 3
Message-driven beans
• Servono per questa applicazione ?
– No; infatti, questa applicazione, come pure le sue
componenti, non devono ricevere comunicazioni
asincrone da parte di altre entità
v. 3
Completare la definizione dei beans
• classificarli rispetto alle varie tipologie
• definire le loro interfacce
• definire i loro metodi
v. 3
Entity beans
• tutti con persistenza gestita dal container, e
nessuno sarà remoto
<<entity>>
Consumer
name: String
surname: String
login: String
{quella che ogni persona
del dipartimento usa nel
suo indirizzo di email}
deb: Euro = 0.00
{il debito corrente}
getDeb(): Euro
pay(Euro)
debit(Euro)
{la definizione di
queste operazioni è
piuttosto ovvia}
<<entity>>
Situation
cash: Euro
{money contained in the cash}
coffee: Int
{numero di busitne disponibili }
key: Int
{ sempre = 1, dato che ci sarà
sempre un unico oggettodi
questa classe}
refil&pay(nBox:Int)
{cash = cash - nBox * 31.00;
quantity = quantity + nBox * 50}
how(): Euro x Int
{return cash, quantity}
sellMon(nPkgs: Int)
{coffee = coffee -nPkgs;
cash = cash + 0.62 * nPkhgs}
sellCred(nPkgs: Int)
{ coffee = coffee - nPkgs}
<<entity>>
Sell
month: Int
year: Int
quantity: Int {in bustine}
key: int
{= month *37 * year * 41}
howmany(): Int
sold(Int)
<<entity>>
Refill
day: int
month: Int
year: Int
quantity: Int
key: int
{= day * 51 * month * 37 * year * 41}
v. 3
Sessions Beans (1)
• H_Sell remoto, statefull
<<session>>
H_Sell
month: int
year: int
currentMonth =[derived] month * 31 * year * 37
sellMon(nPkgs: Int)
{findSituation(1).sellMon(nPkgs);
findSell(currentMonth).sold(nPkgs)}
sellCred(log: String, nPkgs: Int)
{findSituation(1).sellMon(nPkgs);
findSell(currentMonth).sold(nPkgs);
findConsumer(log).debit(nPkgs)}
v. 3
Sessions Beans (2)
• H_Debit remoto, statefull
<<session>>
H_Debit
C: String
debitOf(lg: String): Euro
{C = lg;
findConsumer(C).getDeb();}
pay(E:Euro)
{findConsumer(C).paid(E)}
• Check remoto, stateless
<<session>>
Check
check(): Euro x Int
{return findSituation(1).how(); }
v. 3
Sessions Beans (3)
• Statistic remoto, stateless
<<session>>
Statistic
giveData(D: Date,Y1,Y2: Int): sequence(Int)
{L = [];
for y = y1 to y2 do
for m = 1 to (if yearOf(D) = y then monthOf(D) else 12)
L = L.add(findSell(Y*41 + m * 37).quantity;
return L;}
v. 3
Reusable components
• non abbiamo riusato niente, Ok
• possiamo pensare qualcuna delel nostre
componenti in vista del riuso ? (ovviamente
rendendole un poco più generale)
• Statistic…
• Situation
v. 3
Transaction
• ????
v. 3
Security
• quali problemi, al massimo il furto di qualche Euro
da parte di un mio collega/personale delle pulizie
• autenticare l’unico utente
v. 3
Schema (architettura software)
EJB Container
HSell
Session
Bean
HDebit
Session
Bean
Application
Client
Check
Session
Bean
Statistic
Session
Bean
HRefill
Session
Bean
Consumer
Entity
Bean
Situation
Entity
Bean
Data
base
Sell
Entity
Bean
v. 3
Esercizi
L0] Preparare uno schema per la GUI dell’application
client di Lavaza.
L1] rifare la documentazione sul progetto di Lavaza
presentato in questo documento utilizzando altri
tipi di notazioni, precisando quale usate (es., UML
puro preparato con tools, disegni & testo
completamenti liberi)
L2] modificare il progetto di Lavaza secondo i vostri
gusti, e modificare in modo corrispondente la
documentazione presentato in questo documento
L3] Correggere un grossolano errore presente in
questo progetto
v. 3
Terza puntata
Preparare gli enterprise beans
• Scrivere il codice
• usando le appropriate API
– javax.ejb (fornisce le le interfacce necessarie per gli
enterprise beans)
• compilarlo
• impacchettarle aggiungendo il deployment
descriptor (per mezzo di tools)
– caso session bean
– caso entity bean
v. 3
Session bean (remoto)
• per costruire un session bean (sia esso HSell),
occorre preparare il seguente codice
– Session bean class (HSellBean)
– Home interface (HSellHome)
– Remote interface (HSell)
v. 3
Session bean class
• caratteristiche
– implementa l’interfaccia SessionBean(in javax.ejb)
– è pubblica [visibile ovunque]
– non può essere astratta [non può essere istanziata] o finale
[non può avere sottoclassi]
– implementa uno o più metodi [devono differire per gIi
argomenti] ejbCreate
* permettono di fare alcune cose subito dopo che il bean è stato
creato (~inizializzazione)
– implementa i business metodi
* quelli specifici delal sua attività e scopo
– gli argomenti ed i tipi devono essere validi tipi RMI se il
bean permette l’accesso remoto
– contiene un costruttore pubblico senza parametri
– non deve definire il metodo finalize [quello per distruggere un
v. 3
oggetto direttamente senza aspettare il garbage colector]
Home Interface
• estende l’interfaccia javax.ejb.EJBHome
• per un session bean lo scopo della home interface è di
definire i metodi create che I clienti remoti possono
invocare
• ogni metodo create method nella home interface
corrisponde ad un metodo ejbCreate nella bean class
• I tipi dei metodi create ed ejbCreate sono simili ma
differenti per quello che segue
– il numero e tipo degli argomenti devono corrispondere a a quelli del
corrispondente metodo ejbCreate
– un metodo create ritorna il tipo della remote interface
dell’enterprise bean (ma un ejbCreate ritorna void)
– la clausola throws del metodo create deve includere
java.rmi.RemoteException e javax.ejb.CreateException
v. 3
Remote Interface
• estende javax.ejb.EJBObject
• definisce i metodi (relativi al) business che un
cliente remoto può invocare
• I metodi definiti in una remote interface sono tali
che
– ogni metodo dell’interfaccia remotadeve corrispondere
ad un metodo implementato nella enterprise bean class
– il tipaggio del metodo deve essere identico a quello del
metodo corrispondente nella enterprise bean clas
– gli argomenti ed i tipi devono essere validi tipi RMI
– la clausola throws deve includere
java.rmi.RemoteException
v. 3
Help Classes
• nessuna
v. 3
Per esercizio
• codificare gli altri 4 session beans
• tutti remoti
• qualcuno avrà anche qualche classe helper (Euro)
v. 3
Sources
• Tre file
– HSellBean.java
– HSellHome.java
– Hsell.java
v. 3
Altre features degli enterprise beans
• Environment entries
– permettono di parametrizzare un bean (qualunque genere) con dei
valori, che saranno poi forniti al momento dell’installazione [vedere
dettagli nel tutorial]
– utili nell’applicazione Lavaza per
* …………
• confrontare enterprise bean
– metodo per fare ciò isIdentical
– attenzione
* ok per statefull session bean
* sempre vero per stateless session beans
* per gli entity beans si può anche comparare le loro due chiavi primarie
• passare una referenza a se stesso
– non si può usare this (identità maneggiata dal container)
– usare il metodo getEJBObject dell’interfaccia SessionContext
v. 3
Entity beans (persistenza gestita dal container)
• tutti quelli dell’applicazione Lavaza sono di questo
tipo
• inoltre nessuno è remoto
• prendiamo esempio Consumer
– il container si preoccupa di farlo corrispondere alle
tuple/righe di una relazione
– name: String
– surname: String
– login: String
– deb: Double
• Occorre definire
– Entity bean class (ConsumerBean)
– Local home interface (ConsumerHome)
– Local interface (ConsumerPlayer)
v. 3
Entity bean class
• deve essere definita come pubblica ed astratta
• deve implementare
– l’interfaccia EntityBean
– zero o più metodi ejbCreate ed ejbPostCreate
– i metodi per l’accesso get e set, definiti come astratti,
dei campi persistenti e relazione
– i metodi select necessari, definiti come astratti
– i metodi home
– i metodi relativi al business specifico
• non deve implementare
– i metodi finder
– il metodo finalize
v. 3
Metodi accesso
• il container permette di accedere a dei campi
virtuali corrispondenti agli attributi della relazione
associata al bean
• es. per il campo Surname: String
public abstract String getSurname();
public abstract void setSurname (String id);
• similnente per i campi corrispondenti alle relazioni
(ma in questo caso non ne abbiamo nessuno)
v. 3
Metodi select
• per realizzare queries sul database espresse
usando EJB QL
– definite nel deplyment descriptor
• possono essere chiamati solo dai metodi dell’entity
bean class, ma non dai clienti
• in genere ritornano una collection
• non ce ne sono in Consumer
v. 3
Metodi
• Metodo ejbCreate
– inizializza un’istanza di un entity bean assegnando gli
argomenti ai campi persistenti
– dop il suo completamento, il container iniserisce una
nuova riga nel database
– serve per Consumer ?
– no, ma ci dovrebbe essere, manca la funzionalità per
inserire un nuovo Consumer (serve, per esempio
quando ariva una nuova persona nel dipartimento
– esercizio: Modificare il progetto
• Metodo ejbPostCreate
– come per ejbCreate , ma per inizializzare i campi
relazione
v. 3
Local Home Interface
• definisce i metodi create, finder e home che possono
essere invocati dai clienti locali
• regole sintattiche per un metodo create
– il nome inizia con create
– ha lo stesso numero e tipo di argomenti come il corrispondente
metodo ejbCreate nella classe entity bean
– ritorna il tipo local interface type dell’entity bean
– la clausola throws include le eccezioni del corrispondente metodo
ejbCreate nella classe entity bean, ed anche
javax.ejb.CreateException
• regole sintattiche per un metodo finder
– il nome inizia con find
– il return tipo è quello dell’interfaccia local del bean, o una collezione
di questi tipi
– la clausola throws contiene javax.ejb.FinderException
– il metodo findByPrimaryKey deve essere definito
v. 3
v. 3
Local Interface
• definisce i metodi business ed accesso che un
cliente local può invocare (chiaramente definiti
nella entity bean class)
• nel nostro caso solo pay, debit e getDebit
v. 3
Fine lezione
Application Client
• Un application client J2EE è un programma stand
alone lanciato con una command line o dal
desktop
• che gli enterprise beans in esecuzione su un
application server J2EE
• in genere ha una interfaccia visuale basata su
Swing/AWT
v. 3
Come collegarsi ai beans
• localizzare la home interface del bean di interesse
– basato su JNDI
……
XXXHome home = ….
• creare istanze
XXX myBeanName = home.create();
chiamare i metodi business
myBeanName.METH(…..);
• Al momento della creazione dell’applicazione
verranno fornite le informazioni per realizzare la
prima parte
v. 3
Scarica

bYTEBoss Lavaza3