15-OSFrameworks -45p [Compatibility Mode]

Transcript

15-OSFrameworks -45p [Compatibility Mode]
Open Source
Frameworks
Ingegneria del Software
Andrea Bei
1
Framework
Un framework è un insieme di classi e interfacce che cooperano
e generalizzano task e workflow comuni di uno specifico dominio
applicativo (funzionale o tecnologico)
Un framework ha le seguenti caratteristiche
Accelera la costruzione di applicazioni del dominio a cui si rivolge
grazie al riuso della soluzione architetturale che ne costituisce la
struttura
I componenti del framework sono riusabili
Utilizzo diffuso di classi astratte e interfacce
Considerate come "template" per le sottoclassi o classi delle specifiche
applicazioni.
Adozione di un modello collaborativo
Inversione del flusso di controllo (IOC)
Lo sviluppatore non scrive codice per coordinare le componenti. Lo
sviluppatore implementa le componenti che aderendo alla logica
collaborativa del framework verranno coordinate da quest'ultimo. I
framework assumono il controllo della applicazione e non il contrario! cfr
ad esempio: pattern template method)
2
Framework Open Source
Sono stati tra i principali elementi di innovazione nelle architetture web
negli ultimi anni
Hanno rappresentato il principale veicolo dell’esperienza “collettiva”
degli sviluppatori in termini di design & architectural pattern, idioms,
best practices
Rispetto ai framework in-house (realizzati ad hoc) hanno una
contribuzione di sviluppo più ampia e quindi una maggiore velocità di
convergenza alla soluzione “migliore” per il dominio specifico
Aumentano la produttività nello sviluppo
Supportano la standardizzazione delle soluzioni
Supportano un approccio allo sviluppo architettura-centrico
Per uno sviluppatore/architetto Java EE la competenza su framework e
librerie Open Source è fondamentale
3
Web Application Framework
Un Web Application Framework è:
un sistema software che fornisce struttura e comportamento generalizzati di task e
workflow tipici delle applicazioni web. Es: gestione della navigazione (MVC), gestione
dell’accesso ai dati (DAO), …
Il framework di riferimento di LIS è un Web Application
Framework didattico completo (nel senso che include tutti i task
tipici di una applicazione web dalla presentazione all’accesso ai
dati basandosi sui design pattern fondamentali)
Nella “vita reale” per la realizzazione di web application è tipico
l’utilizzo congiunto di diversi framework open source
specializzati in aspetti specifici
Ci concentreremo su alcuni di quelli più diffusi
Struts / Struts 2
Spring
Hibernate
4
Struts
Struts
E’ un insieme di classi ed interfacce che costituiscono l'infrastruttura per costruire web
application Java EE conformi al design pattern Model 2 (MVC)
Il suo ideatore è Craig McClanahan ed è stato donato alla Apache Software Foundation
nel maggio del 2000 da parte di IBM.
E’ uno dei web application framework più diffusi al mondo
Struts 2
Nonostante il nome, Struts 2 non è una nuova release di Struts ma un framework
completamente nuovo basato su WebWork
Sono state introdotte caratteristiche non presenti in Struts grazie ai feedback di
migliaia di sviluppatori
5
Spring
Spring è un “lightweight” container che fornisce una soluzione per sviluppare
applicazioni costruite su POJO. Si basa su:
Inversion of Control/Dependency Injection (configurazione data-driven di POJO)
AOP (Aspect Oriented Programming)
Diverse componenti di utilità (tra cui una propria implementazione di MVC)
La prima versione venne scritta da Rod Johnson e rilasciata con la pubblicazione
del proprio libro "Expert One-on-One Java EE Design and Development" (Wrox
Press, Ottobre 2002).
Spring è stato largamente riconosciuto all'interno della comunità Java quale
valida alternativa al modello basato su Enterprise JavaBeans (EJB). Rispetto a
quest'ultimo, il framework Spring lascia una maggiore libertà al programmatore
fornendo allo stesso tempo un'ampia e ben documentata gamma di soluzioni
6
semplici adatte alle problematiche più comuni.
Hibernate
Hibernate (H8) è un middleware ORM (Object-relational mapping) open source.
Consente la rappresentazione e la gestione su database relazionale di un
sistema di oggetti Java.
E’ stato originariamente sviluppato da un team internazionale di programmatori
volontari coordinati da Gavin King; in seguito il progetto è stato proseguito sotto
l'egida di JBoss, che ne ha curato la standardizzazione rispetto alle specifiche
Java EE.
7
Mapping dei FW OS con eUniversity
Struts
Hibernate
Spring
8
Struts – class diagram
9
Struts – componenti principali
Struts-config.xml fornisce alla ActionServlet, in base ai
parametri della URL
La Action da invocare
La pagina JSP a cui inoltrare la richiesta
ActionServlet: il controller di Model 2
Action: il Model di Model 2 (Classe base per le classi “action” )
Le classi action sono responsabili di
Interfacciarsi con il layer sottostante (es: EJB, DAO, …)
Recuperare i dati da presentare alla View e inserirli in sessione
JSP: la View di Model 2
Le pagine JSP sono responsabili di
Recuperare i dati da visualizzare dalla sessione
Visualizzare i dati
10
StrutsStruts- esempio di strutsstruts-config
<struts-config>
<form-beans>
<form-bean name=”projectForm” type=”it.uniroma2.app.form.ProjectListForm”/>
</form-beans>
<action-mappings>
<action path=”/tasklist” type=” it.uniroma2.app.action.ProduceTaskListAction”
name=”projectForm” scope=”request” validate=”true” input=”/jsp/Project.jsp”>
<forward name=”success” path=”/jsp/TaskList.jsp”/>
<forward name=”failure” path=”/jsp/ServerErrors.jsp”/>
</action>
</action-mappings>
</struts-config>
11
Bibliografia
Programming Jakarta Struts - Chuck Cavaness
12
Spring - Caratteristiche
Spring è un lightweight container framework che supporta tecniche di
IoC (inversion of control) e AoP (aspect-oriented programming)
Lightweight (“leggero”)
“leggero” per dimensione e overhead di elaborazione. (file JAR circa 1MB)
Inversion of control
Permette di sostenere “low coupling” (basso accoppiamento).
Gli oggetti ricevono passivamente dall’esterno le loro dipendenze (es: il riferimento
ad altri oggetti) , invece di crearle (new di oggetti) o cercarle in file esterni (es:
classloading dinamico). Approccio “push” invece di “pull”.
E’ il container che fornisce le dipendenze all’oggetto all’atto della istanziazione di
quest’ultimo (Dependency Iniection)
Aspect-oriented programming
Permetta la SoC (separation of concern). Ovvero la separazione di responsabilità tra
business logic e system services (come logging, autenticazione, gestione delle
transazioni)
13
Spring - Caratteristiche
Container
Contiene e gestisce il ciclo di vita e la configurazione delle dipendenze degli
oggetti. E’ possibile configurare come ogni singolo bean (POJO) deve essere creato (ad
esempio in modalità “singleton”, pool, classica) e quali sono le sue dipendenze con gli
altri bean.
Framework
Permette di configurare e comporre applicazioni complesse a partire da
componenti più semplici in maniera dichiarativa (XML)
Fornisce funzionalità infrastrutturali riusabili (transaction management,
persistence framework integration, etc.), lasciando al developer solo lo sviluppo
della logica di business
14
Spring Architettura
15
Spring Architettura
Core container
Contiene le funzionalità di base del framework. Contiene il BeanFactory, il “cuore” di ogni
applicazione Spring-based, che che consiste in una implementazione del pattern factory che
utilizza la tecnica IoC
Modulo Application Context
Contiene il supporto per l’internazionalizzazione (I18N messages), gestione degli
eventi del ciclo di vita della applicazione, meccanismi di validazione, servizi come
e-mail, JNDI access, EJB integration, scheduling, integrazione con “templating
framework” come Velocity e FreeMarker
Modulo AOP
E’ il componente base per lo sviluppo di aspects (le API sono conformi a quelle definite
in AOP Alliance . Permette la meta-programmazione. (è possibile aggiungere annotations
per istruire Spring su dove e quando aggiungere aspetti)
16
Spring Architettura
Modulo JDBC e DAO
Aiuta a evitare il codice “boilerplate” proprio di JDBC (connessioni, resultset, …).
Fornisce una astrazione del codice boilerplate e permette di semplificare il codice di
accesso a db. Fornisce un layer di exception relative all’accesso al db “on top” rispetto
a quelle native dei db.
Modulo Web Context and Utility
Si basa sul modulo Application Context e lo specializza per applicazioni. Fornisce il
supporto a task web-oriented (es: file upload) e all’integrazione con Jakarta Struts
.
MVC framework
Fornisce un framework Model/View/Controller (MVC) per la costruzione di web
application. Spring’s MVC framework usa IoC per separare la logica di business e la
logica di controllo e collegare in modo dichiarativo i parametri della request ai relativi
oggetti di business (i.e. actions)
Modulo O/R Mapping
Punto di integrazione per Hibernate, JDO, OJB, iBATIS
17
Spring “hello world”
public interface GreetingService {
public void sayGreeting();
}
public class GreetingServiceImpl implements GreetingService {
private String greeting;
public GreetingServiceImpl() {}
public GreetingServiceImpl(String greeting) {
this.greeting = greeting;
}
public void sayGreeting() {
System.out.println(greeting);
}
public void setGreeting(String greeting) {
this.greeting = greeting;
}
}
GreetingServiceImpl ha un solo attributo (o property): greeting.
La property è l’unica dipendenza della classe può essere impostata tramite il
costruttore o tramite il metodo setter
SPRING IMPOSTA IL VALORE DELLA PROPERTY
18
Spring “hello world”
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id=“greetingService” class="com.springinaction.chapter01.hello.GreetingServiceImpl">
<property name="greeting">
<value>Buenos Dias!</value>
</property>
</bean>
</beans>
TRAMITE SETTER - EQUIVALE A
GreetingServiceImpl greetingService = new GreetingServiceImpl();
greetingService.setGreeting("Buenos Dias!");
19
Spring “hello world”
<bean id="greetingService"
class="com.springinaction.chapter01.hello.GreetingServiceImpl">
<constructor-arg>
<value>Buenos Dias!</value>
</constructor-arg>
</bean>
TRAMITE COSTRUTTORE - EQUIVALE A
GreetingServiceImpl greetingService = new GreetingServiceImpl(“Buenos Dias”);
20
Spring “hello world”
package com.springinaction.chapter01.hello;
import java.io.FileInputStream;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
public class HelloApp {
public static void main(String[] args) throws Exception {
BeanFactory factory = new XmlBeanFactory(new FileInputStream("hello.xml"));
GreetingService greetingService = (GreetingService) factory.getBean("greetingService");
greetingService.sayGreeting();
}
}
Risultato “Hello World”: Come configurare un bean mediante l’injection di una
specifica stringa in una property.
La reale potenzialià di Spring consiste nel poter fare l’injection di un bean in un altro
bean usando IoC
21
IoC (Inversion of control)
Hollywood Principle “Don’t call me, I’ll
call you”.
Lo sviluppatore implementa dei metodi che
verranno chiamati dal framework
E’ una tecnica usata nella progettazione
dei framework
Uno dei pattern per realizzarla è il Template
Method (fig. a destra)
Esempio: Servlet container
Gestisce il ciclo di vita le request delle Servlet
Invocando i metodi callback “Init”,
“Destroy”, “doGet”, “doPost”
abstract class AbstractClass {
public void templateMethod() {
// qui c’è l’algoritmo
...
framework
method1();
while (...) method2();
...
method3();
}
abstract void method1();
abstract void method2();
abstract void method3();
}
class ConcreteClass extends AbstractClass {
void method1() {...}
applicazione
void method2() {...}
void method3() {...}
}
22
Dependency Iniection
E’ un tipo particolare di inversione del controllo
Tradizionalmente nell’ OOP ogni oggetto è responsabile di ottenere i riferimenti agli
oggetti con cui collabora (le sue dipendenze)
Applicando IoC, agli oggetti le dipendenze vengono fornite all’atto della creazione da un
entità esterna che coordina ogni oggetto nel sistema. In altre parole le dipendenze
vengono “iniettate” nell’oggetto
In pratica in Spring il container inietta le dipendenze nell’oggetto tramite i suoi metodi
Java usati come metodi callback (setter o costruttori). Le dipendenze possono essere
oggetti (es: String) o tipi semplici (es: int, float)
.
DI è anche conosciuta come “push configuration”. Le dipendenze sono “spinte dentro”
(push) l’oggetto dal container piuttosto che “prelevate” (pull) dall’oggetto stesso
PULL
PUSH
23
Dependency Injection Pattern
DI Esempio
public class KnightOfTheRoundTable {
private String name;
private HolyGrailQuest quest;
public KnightOfTheRoundTable(String name) {
this.name = name;
quest = new HolyGrailQuest(); -> L’oggetto recupera la propria dipendenza
}
public HolyGrail embarkOnQuest() throws GrailNotFoundException {
return quest.embark();
}}
public class HolyGrailQuest {
public HolyGrailQuest() {}
public HolyGrail embark() throws GrailNotFoundException {
HolyGrail grail = null;
// Look for grail
…
return grail;
}}
24
DI Esempio
import junit.framework.TestCase;
public class KnightOfTheRoundTableTest extends TestCase {
public void testEmbarkOnQuest() {
KnightOfTheRoundTable knight = new KnightOfTheRoundTable("Bedivere");
try {
HolyGrail grail = knight.embarkOnQuest();
assertNotNull(grail);
assertTrue(grail.isHoly());
} catch (GrailNotFoundException e) {
fail();
}}}
Se si esegue il test su KnightOfTheRoundTable, indirettamente si effettua il test
anche su HolyGrailQuest
Inoltre è impossibile avere un comportamento diverso HolyGrailQuest (e.g., return
null o throw GrailNotFoundException) per diversi test
Se si sta utilizzando per HolyGrailQuest un mock object per simulare un oggetto reale
in ambiente di test si deve modificare il codice per farlo funzionare in ambiente di
produzione
25
DI Esempio
Il problema è l’accoppiamento. KnightOfTheRoundTable è staticamente accoppiato con
HolyGrailQuest (non si può avere un KnightOfTheRoundTable senza avere anche un HolyGrailQuest)
L’accoppiamento è necessario ma va minimizzato
Necessario: Due oggetti sono accoppiati quando uno dipende dall’altro, ma un programma OO
in esecuzione è proprio un insieme di oggetti che dipendono l’uno dall’altro (eseguono dei
compiti o delegano l’esecuzione ad altri oggetti dipendenti)
Minimizzato: Va reso più basso possibile perchè riduce la leggibilità, manutenibilità, testabilità
(pattern GRASP “low coupling”). Un modo per ridurre l’accoppiamento diretto è introdurre un
livello di indirezione mediante interfacce
public interface Quest {
public abstract Object embark() throws QuestException;
}
public class HolyGrailQuest implements Quest {
public HolyGrailQuest() {}
public Object embark() throws QuestException {
// Do whatever it means to embark on a quest
return new HolyGrail();
}}
private Quest quest;
…
public Object embarkOnQuest() throws
QuestException {
return quest.embark();
}
Nella classe
KnightOfTheRoundTable uso
il tipo interfaccia
26
DI Esempio
public interface Knight {
public Object embarkOnQuest() throws QuestException;
}
public class KnightOfTheRoundTable implements Knight {
private Quest quest;
…
public KnightOfTheRoundTable(String name) {
quest = new HolyGrailQuest();
… }
public Object embarkOnQuest() throws QuestException {
return quest.embark();
}}
Anche con le interfacce non risolvo il problema perchè un KnightOfTheRoundTable è vincolato
solo ad un tipo di ricerca per “Holy Grail” e nessun altro tipo di ricerca
27
DI Esempio
E’ giusto che il cavaliere scelga da solo la propria ricerca (missione) o è più
conveniente/utile che gli venga assegnata ?
public class KnightOfTheRoundTable implements Knight {
private Quest quest;
…
public KnightOfTheRoundTable(String name) {
…
}
public HolyGrail embarkOnQuest() throws QuestException {
…
return quest.embark();
}
public void setQuest(Quest quest) {
this.quest = quest;
}}
Ora KnightOfTheRoundTable non è più responsabile di recuperare le proprie missioni.
Inoltre poiché KnightOfTheRoundTable è dipendente solo dall’interfaccia Quest è possibile
passargli qualsiasi implementazione di tale interfaccia.
La responsabilità di coordinare la collaborazione tra oggetti dipendenti è scorporata dagli
oggetti stessi.
es: In ambiente di produzione potremmo aver bisogno di un tipo di HolyGrailQuest,28ma
in ambiente di test potremmo avere una implementazione mock (mock object)
DI Esempio
Ora che l’oggetto è pronto a ricevere dall’”esterno” una
dipendenza chi la passa ? QUI ENTRA IN GIOCO SPRING
L’azione di creare associazioni tra componenti applicativi
è detta wiring (cablare/collegare fili elettrici). In Spring,
ci sono molti modi di collegare tra loro componenti ma il
più comune è tramite XML (“knight.xml”)
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="quest“ class="com.springinaction.chapter01.knight.HolyGrailQuest"/>
<bean id="knight“ class="com.springinaction.chapter01.knight.KnightOfTheRoundTable">
<constructor-arg>
<value>Bedivere</value>
</constructor-arg>
<property name="quest">
<ref bean="quest"/>
</property>
</bean>
</beans>
29
DI Esempio
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
public class KnightApp {
public static void main(String[] args) throws Exception {
BeanFactory factory = new XmlBeanFactory(new FileInputStream("knight.xml"));
KnightOfTheRoundTable knight = (KnightOfTheRoundTable)factory.getBean("knight");
knight.embarkOnQuest();
}
}
30
Hibernate - Caratteristiche
Hibernate è un middleware ORM (Object Relational
Mapping).
La funzione principale di un ORM è l’automatica e
trasparente persistenza di oggetti nelle tabelle di un DB
relazionale tramite metadata che descrivono il mapping
tra oggetti e entità del DB. Lo strato ORM trasforma dati
da una rappresentazione e l’altra in entrambi i versi
Ogni middleware ORM comprende i seguenti elementi:
API per eseguire operazioni CRUD (Create Read Update Delete) su
oggetti di classi persistenti
Un linguaggio o API per specificare delle Query su classi e proprietà
di classi
Una “facility” per specificare i mapping metadata
Una tecnica per gestire oggetti transazionali per eseguire dirty
checking, lazy association fetching, ed altre funzioni di ottimizzazione
31
Hibernate “Hello World”
package hello;
public class Message {
private Long id;
private String text;
private Message nextMessage;
private Message() {}
public Message(String text) {
this.text = text;
}
public Long getId() {
return id;
}
private void setId(Long id) {
this.id = id;
}
public String getText() {
return text;
}
Applying advice to an object is known as weaving
public void setText(String text) {
this.text = text;
}
public Message getNextMessage() {
return nextMessage;
}
public void setNextMessage(Message nextMessage) {
this.nextMessage = nextMessage;
}}
32
Hibernate “Hello World”
Session session = getSessionFactory().openSession();
Transaction tx = session.beginTransaction();
Message message = new Message("Hello World");
session.save(message);
tx.commit();
session.close();
equivale a
insert into MESSAGES (MESSAGE_ID, MESSAGE_TEXT, NEXT_MESSAGE_ID)
values (1, 'Hello World', null)
33
Hibernate “Hello World”
Session newSession = getSessionFactory().openSession();
Transaction newTransaction = newSession.beginTransaction();
List messages = newSession.find("from
Message as m order by m.text asc");
System.out.println( messages.size() + " message(s) found:" );
for ( Iterator iter = messages.iterator(); iter.hasNext(); ) {
Message message = (Message) iter.next();
System.out.println( message.getText() );
}
newTransaction.commit();
newSession.close();
Hibernate Query
Language
(HQL)
equivale a
select m.MESSAGE_ID, m.MESSAGE_TEXT, m.NEXT_MESSAGE_ID
from MESSAGES m
order by m.MESSAGE_TEXT asc
34
Hibernate “Hello World”
XML Mapping
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping>
<class name="hello.Message“ table="MESSAGES">
<id name="id“ column="MESSAGE_ID">
<generator class="increment"/>
</id>
<property name="text“ column="MESSAGE_TEXT"/>
<many-to-one name="nextMessage“ cascade="all“ column="NEXT_MESSAGE_ID"/>
</class>
</hibernate-mapping>
35
Hibernate “Hello World”
Session session = getSessionFactory().openSession();
Transaction tx = session.beginTransaction();
// 1 is the generated id of the first message
Message message = (Message) session.load( Message.class, new Long(1) );
message.setText("Greetings Earthling");
Message nextMessage = new Message("Take me to your leader (please)");
message.setNextMessage( nextMessage );
tx.commit();
session.close();
equivale a
select m.MESSAGE_ID, m.MESSAGE_TEXT, m.NEXT_MESSAGE_ID
from MESSAGES m
where m.MESSAGE_ID = 1
insert into MESSAGES (MESSAGE_ID, MESSAGE_TEXT, NEXT_MESSAGE_ID)
values (2, 'Take me to your leader (please)', null)
update MESSAGES
set MESSAGE_TEXT = 'Greetings Earthling', NEXT_MESSAGE_ID = 2
where MESSAGE_ID = 1
36
Hibernate Startup
Startup di Hibernate
Localizzare il file di mapping tramite l’oggetto Configuration
Creare un SessionFactory
Regole
1.
Il file di mapping (Message.hbm.xml) deve essere visibile nel CLASSPATH
2.
Per convenzione 1 map file per classe (è possibile invocare più volte il metodo
addResource per caricarli tutti)
3.
Per impostare le configurazioni 3 alternativa
java -Dproperty=value.
file hibernate.properties nel classpath.
Tag <property> in hibernate.cfg.xml nel classpath.
Equivalente con il method chaining
Configuration cfg = new Configuration();
cfg.addResource("hello/Message.hbm.xml");
cfg.setProperties( System.getProperties() );
SessionFactory sessions = cfg.buildSessionFactory();
Configuration cfg = new
Configuration()
.addResource("hello/Message.hbm.xml")
.setProperties(System.getProperties())
.buildSessionFactory();
37
Connection Pool
Supporto al connection pool open source C3P0 (altri supportati sono Apache DBCP e
Proxool)
Senza Hibernate
Con Hibernate
File
hibernate.properties
hibernate.connection.driver_class = org.postgresql.Driver
hibernate.connection.url = jdbc:postgresql://localhost/auctiondb
hibernate.connection.username = auctionuser
hibernate.connection.password = secret
hibernate.dialect = net.sf.hibernate.dialect.PostgreSQLDialect
hibernate.c3p0.min_size=5
hibernate.c3p0.max_size=20
hibernate.c3p0.timeout=300
hibernate.c3p0.max_statements=50
hibernate.c3p0.idle_test_period=3000
38
Caso di Studio: Modello di DominioDominio-Aste Online
1°Passo: Disegnare il Modello di Dominio
39
Caso di Studio: Modello di DominioDominio-Aste Online
2°Passo: Progettare i POJO (o JavaBean)
public class User implements Serializable {
private String username;
private Address address;
public User() {}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
public MonetaryAmount calcShippingCosts(Address
fromLocation) {
...
}
}
Impl. Serializable
Setter/Getter
Business Method
40
Caso di Studio: Modello di DominioDominio-Aste Online
3°Passo: Progettare le associazioni
public class Category implements Serializable {
private String name;
private Category parentCategory;
private Set childCategories = new HashSet();
public Category() { }
...
public void setName(String name) {
this.name = name;
}
public Set getChildCategories() {
Codice “Scaffolding”
return childCategories;
}
public void setChildCategories(Set childCategories) {
this.childCategories = childCategories;
}
public Category getParentCategory() {
return parentCategory;
}
public void setParentCategory(Category parentCategory)
{
this.parentCategory = parentCategory;
}
}
41
Caso di Studio: Modello di DominioDominio-Aste Online
3°Passo: Progettare le associazioni (…aggiungere el ementi)
Category aParent = new Category();
Category aChild = new Category();
aChild.setParentCategory(aParent);
aParent.getChildCategories().add(aChild);
Codice “Scaffolding”
3°Passo: Progettare associazioni
public class Category {
...
private Set items = new HashSet();
...
public Set getItems() {
return items;
}
public void setItems(Set items) {
this.items = items;
}
}
Codice “Scaffolding”
Categoria > Item
42
Caso di Studio: Modello di DominioDominio-Aste Online
3°Passo: Progettare le associazioni
public class Item {
private String name;
private String description;
...
private Set categories = new HashSet();
...
public Set getCategories() {
Codice “Scaffolding”
return categories;
Item > Categoria
}
private void setCategories(Set categories) {
this.categories = categories;
}
public void addCategory(Category category) {
if (category == null)
throw new IllegalArgumentException("Null category");
category.getItems().add(this);
categories.add(category);}}
43
Caso di Studio: Modello di DominioDominio-Aste Online
4°Passo: Definire i metadata
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping>
<class name="org.hibernate.auction.model.Category“ table="CATEGORY">
<id name="id“ column="CATEGORY_ID“ type="long">
<generator class="native"/>
</id>
<property name="name“ column="NAME“ type="string"/>
</class>
</hibernate-mapping>
44
Bibliografia
Hibernate in Action - CHRISTIAN BAUER-GAVIN KING Manning
45