Notes de cours

100
NSY102 1 NSY102 Conception de logiciels Intranet Memento, Command, template Method et Composite, Iterator, Visitor et les Transactions Notes de cours Cnam Paris jean-michel Douin, douin au cnam point fr 23 Mai 2011

description

NSY102 Conception de logiciels Intranet Memento, Command, template Method et Composite, Iterator, Visitor et les Transactions. Cnam Paris jean-michel Douin, douin au cnam point fr 23 Mai 2011. Notes de cours. Sommaire. Les patrons Memento Sauvegarde et restitution de l’état d’un objet - PowerPoint PPT Presentation

Transcript of Notes de cours

Page 1: Notes de cours

NSY1021

NSY102Conception de logiciels Intranet

Memento, Command, template Method et

Composite, Iterator, Visitoret les Transactions

Notes de cours

Cnam Parisjean-michel Douin, douin au cnam point fr

23 Mai 2011

Page 2: Notes de cours

NSY1022

Sommaire

• Les patrons– Memento

• Sauvegarde et restitution de l’état d’un objet

– Command• Ajout et suppression de « Commande »

– Les « Déjà vus »• Template Method

– Laisser des responsabilités aux sous-classes• Composite

– Hiérarchie, structures de données récursives• Iterator, Visitor

– Parcours d’une structure de données

– Transaction ?• Memento : persistance et mise en œuvre du « rollback » des transactions• Template Method : begin, end, ou rollback• Composite : structure arborescente de requêtes …

– Persistent Layer • une introduction

– Le patron DAO/CRUD• Data Access Object, / Create Retrieve Update Delete

Page 3: Notes de cours

NSY1023

Bibliographie utilisée

• Design Patterns, catalogue de modèles de conception réutilisables

de Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides [Gof95]International thomson publishing France

http://www.fluffycat.com/Java-Design-Patterns/

http://www.cs.wustl.edu/~levine/courses/cs342/patterns/compounding-command_4.pdf

http://www.javapractices.com/Topic189.cjp

DAO & JTA : lire http://www.ibm.com/developerworks/java/library/j-dao/

Pour l’annexe :

http://www.oreilly.com/catalog/hfdesignpat/

Page 4: Notes de cours

NSY1024

Pré-requis

• Notions de

– Les indispensables constructions• Interface, Abstract superclass, delegation…

– Les patrons• Composite en première approche

– Transaction sur une seule base• JDBC, Java DataBase Connection• Commit-rollback

Page 5: Notes de cours

NSY1025

Patron Memento

• Sauvegarde et restitution de l’état interne d’un objet

sans violer le principe d’encapsulation.

– Pas d’accès aux attributs• Structures internes supposées inconnues

– annuler ?

Page 6: Notes de cours

NSY1026

Memento

• Sauvegarde et restitution de l’état interne d’un objet sans violer le principe d’encapsulation.

– Caretaker le conservateur– Memento l’état de l’objet– Originator propose les services de sauvegarde et de restitution

• Un exemple …

Page 7: Notes de cours

NSY1027

Memento exemple : NotePad/Agenda

• NotePad // Originator• NotePad.Memento // Memento Souviens-toi

Page 8: Notes de cours

NSY1028

NotePad / Agenda

• Une classe (très simple) – permettant d’ajouter et de retirer des notes/rdv

• Attention chaque agenda a un nombre limité de notes

public class NotePad implements … { List<String> notes; // délégation …

public void addNote(String note) throws NotePadFullException{

public void remove(String note){…}

Patron Memento• NotePad.Memento une classe interne

– pour la sauvegarde et la restitution de l’agenda

Page 9: Notes de cours

NSY1029

Un Client, et un mémento

public class Client { public static void main(String[] args) throws NotePadFullException { NotePad notes = new NotePad(); notes.addNote("15h : il pleut"); System.out.println("notes : " + notes); Caretaker gardien = new Caretaker(); gardien.setMemento(notes.createMemento()); // sauvegarde notes.addNote("16h : il fait beau"); System.out.println("notes : " + notes); notes.setMemento(gardien.getMemento()); // restitution System.out.println("notes : " + notes);

}}

Page 10: Notes de cours

NSY10210

Caretaker : le conservateur de mémento

public class Caretaker { private NotePad.Memento memento;

public NotePad.Memento getMemento() { return memento; }

public void setMemento(NotePad.Memento memento){ this.memento = memento; }}

Abstraction réussie … n’est-ce pas ?

Page 11: Notes de cours

NSY10211

NotePad et son Memento

public class NotePad { private List<String> notes = new ArrayList<String>(); public void addNote(String note) throws NFE { notes.add(note);} public String toString(){return notes.toString(); } private List<String> getNotes(){return this.notes;} private void setNotes(List<String> notes){this.notes = notes;} public Memento createMemento() { Memento memento = new Memento(); memento.setState(); return memento; } public void setMemento(Memento memento) { memento.getState(); } *NFE = NotePadFullException

Page 12: Notes de cours

NSY10212

NotePad.Memento

……// classe interne et membre

public class Memento{ private List<String> mementoNotes; public void setState(){ // copie* d’un notePad mementoNotes = new ArrayList<String>(getNotes());

}

public void getState(){ setNotes(mementoNotes); } }……}// fin de la classe NotePad

// * copie effectiveen profondeurici String étant Immutable, cela suffit

Page 13: Notes de cours

NSY10213

Conclusion intermédiaire

• Memento

– Objectifs atteints

– Mais

• Une classe dite « externe » sur cet exemple serait difficile à réaliser– Méthodes manquantes …

– Prévoir les méthodes dès la conception de l’ « Originator »– clone, copie en profondeur, Itérateur, Visiteur, ???, …

Page 14: Notes de cours

NSY10214

Patron Commande

• Les opérations de cet Agenda Ajouter, Retirer, Afficher, …

– Comment assurer un couplage faible entre l’agenda et ces(ses) opérateurs ?

– Clé de la réussite : le patron Commande• Ne connaît pas les actions à effectuer• Ne connaît pas les effecteurs• Ne connaît pas grand chose …

• Assemblage, configuration en fonction des besoins

Page 15: Notes de cours

NSY10215

Patron Commande principes sur perenoel.com

• Commande concrète ou abstraite– Au père noël.com que l’on ne connaît pas …

Télécommande Universelle Harmony 1000

Ecran tactile ….Gestion des dispositifs placés dans les placards, à travers les murs et les sols Grâce à la double transmission infrarouge (IR) et radiofréquence (RF), la télécommande Harmony 1000 peut contrôler des dispositifs sans pointage ni ligne de visée. Lorsque vous utilisez la télécommande conjointement avec l’extension Harmony RF Wireless

Dispositifs ou objets que l’on ne connaît pas !

Page 16: Notes de cours

NSY10216

Command, alias Action, Transaction …

• Abstraction des commandes effectuées– Invoker ne sait pas ce qu’il commande ….– Une commande concrète, et un récepteur concret

• Souplesse attendue de ce couplage faible …

Page 17: Notes de cours

NSY10217

L’ exemple suite

• L’exemple précédent : le NotePad / agenda– NotePad : l’agenda

• Ajout de commandes concrètes– Ajouter, retirer, …

• Abstraction de l’invocateur– La télécommande ….

• Et du Récepteur– L’agenda

Page 18: Notes de cours

NSY10218

Command exemple

• NotePad // est le Receiver

Page 19: Notes de cours

NSY10219

L’interface Command

public interface Command<T>{

public void execute(T t) throws Exception;

public void undo();

}

Abstraction réussie !

Voir la télécommande générique

Page 20: Notes de cours

NSY10220

Une « Command » concrète

public class AddCommand implements Command<String>{

private NotePad notes;

public AddCommand(NotePad notes){

this.notes = notes;

}

public void execute(String note) throws Exception{

notes.addNote(note);

}

public void undo(){} // à faire, un Mémento ??

Page 21: Notes de cours

NSY10221

Invoker

Abstraction de la commande effectuéerelier la télécommande aux opérations dont on ignore tout …

public class Invoker{private Command<String> cmd;

public Invoker(Command<String> cmd){ this.cmd = cmd;

}

public void addNotePad(String note){cmd.execute(note);

}

public void undo(){cmd.undo();

}}

Une commande concrètesera transmise

Page 22: Notes de cours

NSY10222

Un Client

public class ClientCommand {

public static void main(String[] args) throws Exception {

NotePad notes = new NotePad();

Invoker invoke = new Invoker(new AddCommand(notes));

invoke.addNotePad(" 15h : il pleut");

System.out.println(notes);

invoke.addNotePad(" 16h : il fait beau");

System.out.println(notes);

Page 23: Notes de cours

NSY10223

Discussion

• Patron Command– Abstraction réussie

– De l’invocateur et du récepteur

– …

– Reste en suspend la Commande undo• Un memento !

Page 24: Notes de cours

NSY10224

Command & Memento

public class AddCommand implements Command<String>{ private NotePad notes; private Caretaker gardien; // le conservateur

public AddCommand(NotePad notepad){this.notes = notepad;gardien = new Caretaker();

}

public void execute(String note){ gardien.setMemento(notes.createMemento()); // sauvegarde try{

notes.addNote(note); }catch(NotePadFullException e){}

}

public void undo(){// restitution // note : doit être précédé par au moins un appel de execute notes.setMemento(gardien.getMemento());}}

// rien en cas d’erreur ??

Page 25: Notes de cours

NSY10225

Un Client

public class ClientCommand2 {

public static void main(String[] args) {

NotePad notes = new NotePad();

Invoker invoke = new Invoker(new AddCommand(notes));

invoke.addNotePad("15h : il pleut");

System.out.println(notes);

invoke.addNotePad(" 16h : il fait beau ");

System.out.println(notes);

invoke.undo();

System.out.println(notes);

en cas d’erreur ?? En suspend …

Page 26: Notes de cours

NSY10226

Démonstration …

Page 27: Notes de cours

NSY10227

Une démonstration qui échoue …

• Lorsque l’agenda est rempli !

• Comment est-ce possible ?

À suivre… de près

Page 28: Notes de cours

NSY10228

Combinaison de pattern

• Commande + Memento

– Fructueuse

– Discussion

Page 29: Notes de cours

NSY10229

Command : un peu plus

• MacroCommande– Un ensemble de commandes à exécuter

• MacroCommand<T> implements Command<T>

Page 30: Notes de cours

NSY10230

La classe MacroCommand

public class MacroCommand<T> implements Command<T>{

private Command<T>[] commands;

public MacroCommand(Command<T>[] commands){

this.commands = commands;

}

public void execute(T t){

for(Command<T> cmd : commands)

cmd.execute(t);

}

public void undo(){ …}

}

Page 31: Notes de cours

NSY10231

Patron Command & AWT

• Patron déjà présent dans l’AWT ?

– À chaque clic sur un « JButton »,

• C’est le patron Command qui est employé

• Soit Command + Observateur/Observé

• Voir en annexe

Page 32: Notes de cours

NSY10232

Command

• Critiques

– Une commande concrète par classe

– Factorisation difficile …

– Sauf si …// on utilise le patron Template Method …

Page 33: Notes de cours

NSY10233

Template Method

• Nous laissons aux sous-classes de grandes initiatives …

Page 34: Notes de cours

NSY10234

Template Method, exemple

public class AbstractClass{

protected abstract void avant();

protected abstract void après();

public final void operation(){

avant();

// appel de méthodes ici

après();

}

}

avant/aprèsComme un begin/end/rollback d’une Transaction ?

Page 35: Notes de cours

NSY10235

Template Method = AbstractTransaction ?

public final void execute(T t){

try{

beginTransaction();

// appel de méthodes ici

endTransaction();

}catch(Exception e){

rollbackTransaction();

}

}

protected abstract void beginTransaction();

protected abstract void endTransaction();

protected abstract void rollbackTransaction();

Page 36: Notes de cours

NSY10236

Command & Template Method

public interface Command<T>{ public abstract void execute(T t);}

public abstract class Transaction<T> implements Command<T>{

protected abstract void beginTransaction(); protected abstract void endTransaction(); protected abstract void rollbackTransaction();

public final void execute(T t){ try{ beginTransaction(); atomic_execute(t); // instruction dite atomique endTransaction(); }catch(Exception e){ rollbackTransaction(); } }

Page 37: Notes de cours

NSY10237

Transaction « Sûre »

public class TransactionSure<T> extends Transaction<T>{ protected void beginTransaction(){ // sauvegarde de l’état (Memento) } protected void endTransaction(){ // fin normale } proptected void rollbackTransaction(){ // restitution de l’état (Memento) }

}

Page 38: Notes de cours

NSY10238

Et le patron Memento , souvenons-nous …

public class TransactionSure<T> extends Transaction<T>{ private Contexte ctxt; private CareTaker gardien;

public class TransactionSure(Contexte ctxt){ …}

protected void beginTransaction(){ gardien.setMemento(ctxt.createMemento()); } protected void endTransaction(){ // fin normale } protected void rollbackTransaction(){ ctxt.setMemento(gardien.getMemento()); }}

Page 39: Notes de cours

NSY10239

Avec l’exemple initial, une nouvelle commande

• TransactionAdd et TransactionSure

Page 40: Notes de cours

NSY10240

Add transactionnel

public abstract class TransactionAdd implements Command<String>{

protected abstract void beginTransaction(); protected abstract void endTransaction(); protected abstract void rollbackTransaction(); protected NotePad notes; public TransactionAdd(NotePad notepad){ this.notes = notepad;}

public final void execute(String note){ try{ beginTransaction(); notes.addNote(note); endTransaction(); }catch(Exception e){ rollbackTransaction(); } } }

Page 41: Notes de cours

NSY10241

TransactionSure

public class TransactionSure extends TransactionAdd{ private Caretaker gardien; public TransactionSure(NotePad notes){

super(notes);this.gardien = new Caretaker();

}

protected void beginTransaction(){ gardien.setMemento(notes.createMemento()); }

protected void endTransaction(){ //gardien.oublie(); }

protected void rollbackTransaction(){ notes.setMemento(gardien.getMemento()); } }

Page 42: Notes de cours

NSY10242

Le client

public class ClientCommand2 {

public static void main(String[] args) throws Exception {

NotePad notes = new NotePad();

Invoker invoke = new Invoker(new TransactionSure(notes));

invoke.addNotePad("15h : il pleut");

System.out.println(notes);

invoke.addNotePad(" 16h : il fait beau ");

System.out.println(notes);

Couplage faible …

Page 43: Notes de cours

NSY10243

Conclusion à Trois Patrons

• Command + Memento + Template Method

Memento

Command

Template Method

Memento

Memento

Page 44: Notes de cours

NSY10244

Plusieurs NotePad ?

• Plusieurs NotePad/Agenda mais combien ?

– Synchronisés ?

– Structuration ?

– Parcours ?

– Une solution :

• Le Patron Composite

– Et les transactions ?

– Et le parcours ?, Itérateur, Visiteur

Page 45: Notes de cours

NSY10245

Composite

• Hiérarchie, arbres, …

Page 46: Notes de cours

NSY10246

Composite de NotePad/vers Agenda distribué ?

public abstract class NotePadComponent{

public abstract void addNote(String note) throws NotePadFullException;

public abstract void remove(String note);

public abstract String toString();

}

Page 47: Notes de cours

NSY10247

Classe NotePadComposite

public class NotePadComposite extends NotePadComponent{ private List<NotePadComponent> list; public NotePadComposite(){ list = new ArrayList<NotePadComponent>(); } public void addNote(String note) throws NotePadFullException{ for(NotePadComponent n : list) n.addNote(note); }

public void remove(String note){…} public String toString(){…} public void addChild(NotePadComponent notePad){ list.add(notePad); }

Page 48: Notes de cours

NSY10248

Hiérarchie d’agendas ? Pierre Pol et Jak

• 3 agendas un seul nom – Un composite d’agendas nommé agendas

public static void testSimple() throws NotePadFullException{ NotePadComposite agendas = new NotePadComposite(); NotePad agendaDePierre = new NotePad(5); NotePad agendaDePol = new NotePad(15); NotePad agendaDeJak = new NotePad(7);

agendas.addChild(agendaDePierre); agendas.addChild(agendaDePol); agendas.addChild(agendaDeJak); agendas.addNote("21h : salle des fêtes"); System.out.println(agendas); }

Page 49: Notes de cours

NSY10249

Une autre composition, l’agent et Pierre Pol Jak

public static void testSimple() throws NotePadFullException{

NotePadComposite groupe = new NotePadComposite();

NotePad agendaDePierre = new NotePad(5);

NotePad agendaDePol = new NotePad(15);

NotePad agendaDeJak = new NotePad(7);

groupe.addChild(agendaDePierre);

groupe.addChild(agendaDePol);

groupe.addChild(agendaDeJak);

NotePadComposite agenda = new NotePadComposite();

NotePad agent = new NotePad(15);

agenda.addChild(agent);

agenda.addChild(groupe);

agenda.addNote("21h : salle des fêtes");

System.out.println(agenda);

}

Page 50: Notes de cours

NSY10250

Mais …

• Équité entre les agendas (leur possesseur ?)

– Si l’un d’entre eux est « rempli » (une exception est levée … NFE*)

– Que fait-on ?• La réunion reste programmée …

Ou bien • La réunion est annulée

-> Transaction à la rescousse

* NotePadFullException

Page 51: Notes de cours

NSY10251

Transaction ?

• Si l’un des agendas est « rempli »

– Levée de l’exception NotePadFullException

– Opération atomique :

Alors

– Template Method + Command + Composite + Memento• C’est tout ? …

Page 52: Notes de cours

NSY10252

Template & Command

public interface Command<T>{ public void execute(T t); public void undo();}

public abstract class Transaction implements Command<String>{ protected NotePadComponent notePad;

protected abstract void beginTransaction(); protected abstract void endTransaction(); protected abstract void rollbackTransaction();

public Transaction (NotePadComponent notePad){this. notePad = notePad;

}

Page 53: Notes de cours

NSY10253

Transaction suite

public void execute(String note){

try{

beginTransaction(); notePad.addNote(note);

endTransaction(); }catch(Exception e){

rollbackTransaction();

}

}

}

Déjà vu …

Page 54: Notes de cours

NSY10254

Parfois le besoin d’un itérateur est pressant …

• Patron Composite + Itérateur– Le bien connu

public class NotePadComposite

extends NotePadComponent

implements Iterable<NotePadComponent>{

public Iterator<NodePadComponent> iterator(){

return …

}

Page 55: Notes de cours

NSY10255

Discussion, petite conclusion à 4 patrons

Template Method

+

Command

+

Composite/Iterator *

+

Memento de Composite

=

?

* voir en annexe, un itérateur de composite extrait de http://www.oreilly.com/catalog/hfdesignpat/

Page 56: Notes de cours

NSY10256

L’Itérateur : parfois complexe … un extrait

public Iterator<NotePadComponent> iterator(){ return new CompositeIterator(list.iterator()); } private class CompositeIterator implements Iterator<NotePadComponent>{ private Stack<Iterator<NotePadComponent>> stk;

public CompositeIterator(Iterator<NotePadComponent> iterator){ stk = new Stack<Iterator<NotePadComponent>>(); stk.push(iterator); }

public boolean hasNext(){ if(stk.empty()) return false; while( !stk.empty() && !stk.peek().hasNext()){

stk.pop(); }

return !stk.empty(); }

public NotePadComponent next(){ if(hasNext()){ …

migraine en vue ?, non seulement un extrait de Design Pattern tête la première …

Page 57: Notes de cours

NSY10257

À visiter … vaut le détour

• Patron Iterator– Parcours du Composite (le code complet est en annexe)

public interface Iterator<T>{

  boolean hasNext()

E next();

void remove(); // optionnel

}        

• Patron Visitor– Parcours défini par le client, une visite par nœud concret du Composite

Page 58: Notes de cours

NSY10258

Le patron Visitor

public class abstract Visitor<T>{ public abstract T visit(NotePad notePad);

public abstract T visit(NotePadComposite notePad);}

– La Racine du Composite, contient la méthode accept public abstract <T> T accept(Visitor<T> visitor);

– Toutes les classes, feuilles du composite installent cette méthodepublic <T> T accept(Visitor<T> visitor){ return visitor.visit(this);}

Page 59: Notes de cours

NSY10259

Le Composite nouveau

La classe Racine du Composite s’est enrichie

public abstract class NotePadComponent { public abstract void addNote(String note) throws NotePadFullException; public abstract void remove(String note); public abstract List<String> getNotes(); public abstract String toString();

public abstract <T> T accept(Visitor<T> visitor);}

Chaque classe concrète Nœud déclenche la visite appropriéepublic class NotePad extends NotePadComponent { …

public <T> T accept(Visitor<T> visitor){ return visitor.visit(this); }}

Page 60: Notes de cours

NSY10260

Les visiteurs

• Tout type de visite à la charge du client tout devient possible …• Plus simple : c’est au « client » de le faire … une bonne idée…

Page 61: Notes de cours

NSY10261

Un CloneVisitor

public class CloneVisitor extends Visitor<NotePadComponent>{

public NotePadComponent visit(NotePad notePad){ NotePad clone = new NotePad(notePad.getCapacity()); try{ for(String note : notePad.getNotes()){ clone.addNote(note); } return clone; }catch(NotePadFullException e){return null;} } public NotePadComponent visit(NotePadComposite notePad){ NotePadComposite clone = new NotePadComposite(); for( NotePadComponent n : notePad.getChildren()){ clone.addChild(n.accept(this)); } return clone; }}

Page 62: Notes de cours

NSY10262

Un test parmi d’autres

public void testAgentPierPolJak_Visitors(){ try{ NotePadComposite groupe = new NotePadComposite(); NotePad agendaDePierre = new NotePad(5); NotePad agendaDePol = new NotePad(15); NotePad agendaDeJak = new NotePad(7); groupe.addChild(agendaDePierre);groupe.addChild(agendaDePol); groupe.addChild(agendaDeJak); NotePadComposite agenda = new NotePadComposite(); NotePad agent = new NotePad(15); agenda.addChild(agent); agenda.addChild(groupe);

NotePadComponent clone = agenda.accept(new CloneVisitor());

System.out.println("clone.toString() : " + clone);System.out.println("clone_visitor : " + clone.accept(new StringVisitor()) );

}catch(NotePadFullException e){ fail(" agenda plein ? ");

}catch(Exception e){ fail("exception inattendue ??? " + e.getMessage()); }}

Page 63: Notes de cours

NSY10263

Conclusion à 5 Patrons

Template Method + Command + Composite/Iterator + Memento/Visitor (CloneVisitor)=?

Page 64: Notes de cours

NSY10264

Transactions le retour

• Transaction : JDBC– Base de données relationnelles

• Objet table colonne/ligne

– Syntaxe• executeQuery, executeUpdate

– Introduction • L’article de Yoder• Un exemple de DAO

• JDBC : Transaction locale, une seule base• JTA : Transaction sur plusieurs bases

– Java Transaction API

Page 65: Notes de cours

NSY10265

JDBC : rappels ?

• Interrogation de la base : voir en annexe un exemple avec hsqldb• Base 100% java : HSQLDB www.hsqldb.org

• API JDBC assure un couplage faible Application Java/ Base de données

• image extraite de http://pagesperso-orange.fr/emmanuel.remy/Java/Tutoriels/ProgrammationReseau/JDBC.htm

Page 66: Notes de cours

NSY10266

Base de données et Transactions

public void miseAJourAgenda() throws Exception{ Class.forName("org.hsqldb.jdbcDriver"); // driver hsqldb/jdbc Connection conn = DriverManager.getConnection( "jdbc:hsqldb:http://localhost:8181/LA_BASE", "sa", "");

conn.setAutoCommit(false); Statement stmt = conn.createStatement();

try{ stmt.executeUpdate("update agenda_pier ... "); stmt.executeUpdate("update agenda_pol ... "); stmt.executeUpdate("update agenda_jak ... "); conn.commit();

}catch( Exception e){ conn.rollback(); }}

Page 67: Notes de cours

NSY10267

Agenda est un objet

• Comment le rendre persistant ?– Tout en assurant un couplage faible

• Ressource/Base de données• Objets base de données relationnelle ?

– Le patron DAO

• Data Access Object

• Propose les 4 opérations CRUD– Create Retrieve Update Delete

Page 68: Notes de cours

NSY10268

DAO<T,ID> / CRUD

/** * T pour Le type souhaité * ID pour l'identifiant * CRUD pour create/retrieve/update/delete*/public interface DAO<T,ID>{

public void create(T t) throws Exception; public T retrieve(ID id) throws Exception; public void update(T t) throws Exception; public void delete(ID id) throws Exception; }

* Éventuellement complétée par List<T> findAll()

Page 69: Notes de cours

NSY10269

Implémentation dédié NotePad (1)

public class DBNotePadDAO implements DAO<NotePad,UID> {

private PreparedStatement createStmt; private PreparedStatement retrieveStmt; private PreparedStatement updateStmt; private PreparedStatement deleteStmt; private Connection conn;

public DBNotePadDAO(DataBase db) throws Exception{

this.conn = db.getConnection(); this.createStmt = conn.prepareStatement("INSERT INTO notepads (uid,capacity,notes) VALUES(?,?,?)");

this.retrieveStmt = conn.prepareStatement("SELECT uid,capacity,notes FROM notepads WHERE uid=?");

this.updateStmt = conn.prepareStatement("UPDATE notepads SET notes=? WHERE uid=?");

this.deleteStmt = conn.prepareStatement("DELETE FROM notepads WHERE uid=?");}

Page 70: Notes de cours

NSY10270

Implémentation DAO/CRUD suite

Affectation des paramètres de la requête SQL

INSERT INTO notepads (uid,capacity,notes) VALUES(?, ?, ?) 1 2 3

public void create(NotePad np) throws Exception{ createStmt.setString(1,np.getUID().toString()); createStmt.setInt(2, np.getCapacity()); createStmt.setString(3, np.getNotes().toString()); createStmt.executeUpdate(); }

public NotePad retrieve(UID uid) throws Exception{…}

Page 71: Notes de cours

NSY10271

Implémentation DAO/CRUD suite

// UPDATE notepads SET notes=? WHERE uid=?

public void update(NotePad np) throws Exception{

updateStmt.setString(1, np.getNotes().toString());

updateStmt.setString(2, np.getUID().toString());

updateStmt.executeUpdate();

}

// DELETE FROM notepads WHERE uid=?

public void delete(UID uid) throws Exception{

deleteStmt.setString(1, uid.toString());

deleteStmt.executeUpdate();

}

Page 72: Notes de cours

NSY10272

NotePad en BdD, son nom est unique

NotePad np = new NotePad ("note_nsy102", 10);

np.addNote("lundi:xxx");

np.addNote("mardi:yyy");

DAO<NotePad,String> dao = new DBNotePadDAO(hsqldb);

dao.create(np);

NotePad np1=dao.retrieve("note_nsy102");

Page 73: Notes de cours

NSY10273

NotePad en BdD, son ID est unique

NotePad np = new NotePad(10);np.setUID(new UID());np.addNote("lundi:xxx");np.addNote("mardi:yyy");

DAO<NotePad,UID> dao = new DBNotePadDAO(hsqldb);dao.create(np);

NotePad np1=dao.retrieve(np.getUID());

UID ? : voir java.rmi.server.UID

Page 74: Notes de cours

NSY10274

Transaction & JDBC

• Questions ?– Comment assurer un couplage faible ?

• Objet BDD (en générale relationnelle)

– Comment associer Objet et table de la base de données ?• Plug-in eclipse …• JDO Object Relational Bridge

– Comment obtenir un numéro unique ?

– Comment s’affranchir des dialectes SQL ?

– Comment associer les types Java avec les types SQL ?– ….

• Lire ce que propose Yoder et all dans son article :– http://jfod.cnam.fr/NSY102/lectures/yoder98connecting.pdf

Page 75: Notes de cours

NSY10275

Yoder et all

Page 76: Notes de cours

NSY10276

Transaction et JTA

• JDBC : transaction sur une seule base

“JTA is a high level, implementation independent, protocol independent API that allows applications and application servers to access transactions.”

– java.sun.com Resourcemanager

Application Transactionmanager

Resourcemanager

Resourcemanager

Page 77: Notes de cours

NSY10277

JTA les participants

• Connections JDBC• JMS Queues• JMS Topics

• Enterprise Java Beans• JDO PersistenceManager objects

– http://db.apache.org/ojb/docu/tutorials/jdo-tutorial.html

Page 78: Notes de cours

NSY10278

JTA

• Lire

• http://www.ibm.com/developerworks/library/j-dao/

• Et

• www.pjug.org/jta-j2ee-pjug-2003-07-22.ppt– Dont certaines images ont été extraites

Page 79: Notes de cours

NSY10279

JTA Java Transaction API

http://www.orionserver.com/docs/specifications/jta-spec1_0_1.pdfhttp://www.inf.fu-berlin.de/inst/ag-se/teaching/V-JEE-2006/2007-01-19/Container_Services_for_Transactions.pdfhttp://www.pjug.org/jta-j2ee-pjug-2003-07-22.ppt

Page 80: Notes de cours

NSY10280

JTA 3 composantes

• 1) Application Interface– .javax.transaction.UserTransaction

• 2) Adaptateur au standard X/Open XA protocol– .javax.transaction.xa.XAResource

• (Voir XASession, JMS)

• 3) Interfaces utilisées par le serveur– .javax.transaction.TransactionManager– .javax.transaction.Transaction

Page 81: Notes de cours

NSY10281

JTA … les transactions : le retour

javax.transaction.UserTransaction

// get the system property value configured by administratorString utxPropVal = System.getProperty("jta.UserTransaction");

// use JNDI to locate the UserTransaction object

Context ctx = new InitialContext();UserTransaction utx =

(UserTransaction)ctx.lookup(utxPropVal);

// start transaction work..utx.begin();.. do workutx.commit();

Page 82: Notes de cours

NSY10282

UserTransaction

public interface javax.transaction.UserTransaction{

public abstract void begin();public abstract void commit();public abstract int getStatus();public abstract void rollback();public abstract void setRollbackOnly();public abstract void setTransactionTimeout(int

seconds);}

Page 83: Notes de cours

NSY10283

Conclusion

• Assemblage de Patrons

• Transaction

• Transaction distribuée– JTA

– Persistance des objets JDO

Page 84: Notes de cours

NSY10284

Annexes

• Command et AWT

• Patron Composite et parcours

– Souvent récursif, « intra-classe »

– Avec un itérateur• Même recette …• Une pile mémorise l’itérateur de chaque classe « composite »

• HSQLDB/JDBC

Page 85: Notes de cours

NSY10285

Command et java.awt.*

• Button, MenuItem sont les invocateurs

• ActionListener la Commande

• Une implémentation d’ActionListener : une commande concrète

• Le code d’ActionListener contient l’appel du récepteur

• Exemple extrait de – http://www.cs.wustl.edu/~levine/courses/cs342/patterns/compounding-

command_4.pdf

Page 86: Notes de cours

NSY10286

Command ActionListener …

Extrait de http://www.cs.wustl.edu/~levine/courses/cs342/patterns/compounding-command_4.pdf

Page 87: Notes de cours

NSY10287

Est-ce bien le patron command ?

• « Quit » est l’invocateur

• ActionListener : Command– actionPerformed comme execute,…

• System.exit(0) : Receiver

Page 88: Notes de cours

NSY10288

Composite et Iterator

• Structure récursive  « habituelle »

Composant

CompositeFeuille

Page 89: Notes de cours

NSY10289

En partie extrait de http://www.oreilly.com/catalog/hfdesignpat/

public class Composite extends Composant implements Iterable<Composant>{ private List<Composite> liste; public Composite(…){ this.liste = … } public void ajouter(Composant c){ liste.add(c); }

public Iterator<Composant> iterator(){ return new CompositeIterator(liste.iterator()); }

• Classe Composite : un schéma

Page 90: Notes de cours

NSY10290

CompositeIterator : comme sous-classe

private class CompositeIterator implements Iterator<Composant>{

// une pile d’itérateurs,

// un itérateur par commposite

private Stack<Iterator<Composant>> stk;

public CompositeIterator (Iterator<Composant> iterator){

this.stk = new Stack<Iterator<Composant>>();

this.stk.push(iterator);

}

Page 91: Notes de cours

NSY10291

next

public Composant next(){ if(hasNext()){ Iterator<Composant> iterator = stk.peek(); Composant cpt = iterator.next(); if(cpt instanceof Composite){ Composite gr = (Composite)cpt; stk.push(gr.liste.iterator()); } return cpt; }else{ throw new NoSuchElementException(); } } public void remove(){ throw new UnsupportedOperationException(); } }

Page 92: Notes de cours

NSY10292

hasNext

public boolean hasNext(){

if(stk.empty()){

return false;

}else{

Iterator<Composant> iterator = stk.peek();

if( !iterator.hasNext()){

stk.pop();

return hasNext();

}else{

return true;

}

}

}

Page 93: Notes de cours

NSY10293

Un test unitaire possible

public void testIterator (){ try{ Composite g = new Composite(); g.ajouter(new Composant()); g.ajouter(new Composant()); g.ajouter(new Composant()); Composite g1 = new Composite(); g1.ajouter(new Composant()); g1.ajouter(new Composant()); g.ajouter(g1);

for(Composite cpt : g){ System.out.println(cpt);}

Iterator<Composite> it = g.iterator(); assertTrue(it.next() instanceof Composant); assertTrue(it.next() instanceof Composant); assertTrue(it.next() instanceof Composant); assertTrue(it.next() instanceof Groupe); // etc.

Page 94: Notes de cours

NSY10294

Composite & Iterator : l’exemple NotePad

public Iterator<NotePadComponent> iterator(){

return new CompositeIterator(list.iterator());

}

private class CompositeIterator implements Iterator<NotePadComponent>{ private Stack<Iterator<NotePadComponent>> stk;

public CompositeIterator(Iterator<NotePadComponent> iterator){

stk = new Stack<Iterator<NotePadComponent>>();

stk.push(iterator);

}

public boolean hasNext(){

if(stk.empty()) return false;

while( !stk.empty() && !stk.peek().hasNext()) stk.pop();

return !stk.empty() && stk.peek().hasNext();

}

Page 95: Notes de cours

NSY10295

NotePadComposite

public NotePadComponent next(){ if(hasNext()){ Iterator<NotePadComponent> iterator = stk.peek(); NotePadComponent notepad = iterator.next(); if(notepad instanceof NotePadComposite){ NotePadComposite composite = (NotePadComposite)notepad; stk.push(composite.list.iterator()); } return notepad; }else{ throw new NoSuchElementException(); } } public void remove(){ throw new UnsupportedOperationException(); }}

Page 96: Notes de cours

NSY10296

Annexe 3 Java/JDBC

package java.sql• Chargement du "driver" associé à la base• classe Connection

– 1) établir une connexion avec la base

• classe Statement– 2) engendre une instruction : syntaxe SQL

• classe ResultSet– 3) exécution

• ResultSet rs = stmt.executeQuery("select * from ….. ")

– puis rs.next()

• int res = stmt.executeUpdate("insert into …. ")

Page 97: Notes de cours

NSY10297

HSQLDB

• http://www.hsqldb.org – voir également ce résumé en

• http://best-practice-software-engineering.ifs.tuwien.ac.at/technology/tech-hsqldb.html

• Chargement du "driver"– Class.forName("org.hsqldb.jdbcDriver");

• Établir une connexion :Connection con = DriverManager.getConnection(

String url,String user,String password)

• Quelles sont les url ?, où est la base ?

– Mémoire url = jdbc.hsqldb:.– Fichier local url = jdbc.hsqldb:test– Socket url = jdbc.hsqldb://localhost– Web / HTTP url = jdbc.hsqldb:http//localhost/

Page 98: Notes de cours

NSY10298

Statement et plus

Page 99: Notes de cours

NSY10299

HSQLDB, java/JDBC, suite

• Un exemple :Class.forName("org.hsqldb.jdbcDriver"); // driver jdbc

con = DriverManager.getConnection( "jdbc:hsqldb:COMPTE_BASE", // url "sa", // user ""); // password

stmt = con.createStatement();int res=stmt.executeUpdate("create table comptes …… ");

ResultSet rs =stmt.executeQuery("select * from comptes");

int res=stmt.executeUpdate("insert into comptes …… ");

Page 100: Notes de cours

NSY102100

JDO

• http://db.apache.org/ojb/docu/tutorials/jdo-tutorial.html