tecniche di progetto (a.k.a. design patterns). progettazione object-oriented passi della prassi...
TRANSCRIPT
![Page 1: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/1.jpg)
Tecniche di Progetto(a.k.a. Design Patterns)
![Page 2: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/2.jpg)
Progettazione Object-Oriented
Passi della prassi
• Definizione delle classi
• Determinazione delle responsabilità di ciascuna classe
• Descrizione delle relazioni tra classi
![Page 3: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/3.jpg)
Scoperta delle classi
• Classi rappresentano concetti ed entità entità concrete: conti bancari, forme geometriche, … concetti astratti: streams …
![Page 4: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/4.jpg)
Relazioni tra classi
• Ereditarietà (sottotipo)
• Aggregazione
• Dipendenza
![Page 5: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/5.jpg)
Ereditarietà
• Relazione is-a
• Stabilita tra una classe generale ed una sua specializzazione ogni savings accoung è un bank account ogni cerchio è una ellisse …
Continued…
![Page 6: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/6.jpg)
Aggregazione
• Relazione has-a
• Oggetti di una classe contengono riferimenti ad oggetti di un altra classe
• Ogni automobile ha una ruota (in realtà ne ha quattro … )
• Da non confondere con ereditarietà
![Page 7: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/7.jpg)
is-a vs has-a
class Car extends Vehicle{ . . . private Tire[] tires;}
![Page 8: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/8.jpg)
Dipendenza
• Una relazione di uso
• Esempio: molte delle applicazioni che abbiamo visto dipendono dalla classe Scanner
• Aggregazione è una forma più forte di dipendenza
![Page 9: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/9.jpg)
Progettazione Object-Oriented
Passi della prassi
• Definizione delle classi
• Determinazione delle responsabilità di ciascuna classe
• Descrizione delle relazioni tra classi
Obiettivi
• Garantire astrazione
• Massimizzare riuso
![Page 10: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/10.jpg)
• Progetto componenti astratte pattern: iterator
• Progetto di componenti riusabili/polimorfe tecniche comuni di refactoring e generalizzazione patterns: template, strategy, visitor, decorator …
![Page 11: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/11.jpg)
Progetto di componenti astratte
TIPI DI DATO: Abstract vs Concrete
• Lista astratta Una sequenza ordinata di elementi di un certo tipo
che si possono enumerare con un iteratore
• Lista concreta Una sequenza di nodi che puntano ad oggetti di un
certo tipo e sono collegati mendiante riferimenti
![Page 12: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/12.jpg)
Una lista astratta
![Page 13: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/13.jpg)
Una lista concreta
![Page 14: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/14.jpg)
Un ListIterator astratto
![Page 15: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/15.jpg)
Un ListIterator concreto
![Page 16: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/16.jpg)
Pattern – Iterator
ConcreteCollection<E>
iterator(). . .
AbstractCollection<E>
iterator(). . .
return new ConcreteIterator<E>(this)
Client Iterator<E>
next()hasNext()
ConcreteIterator<E>
![Page 17: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/17.jpg)
Progetto di componenti polimorfe
• Polimorfo ~ Riutilizzabile
• Generics forniscono un meccanismo diretto per ottenere componenti riutilizzabili
• Ereditarietà e aggregazione possono essere altrettanto efficaci alcune tecniche standard codificate in design patterns
![Page 18: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/18.jpg)
Refactoring
• Identificare segmenti di codice ricorrenti che realizzano la medesima logica
• Definire una nuova componente generica che realizza quella logica in modo univoco
• Ristrutturare il codice così da sostituire le ripetizioni di codice con riferimenti alla componente generica
![Page 19: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/19.jpg)
Refactoring di una classe
class Computation // Prima del refactoring
{ void method1(...) { ... step1(); step2(); step3(); ... }
void method2(...) { ... step1(); step2(); step3(); ... }}
Continua…
![Page 20: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/20.jpg)
Refactoring di una classeclass Computation // Dopo del refactoring { void private computeAll() { step1(); step2(); step3(); }
void method1(...) { ... computeAll(); ... }
void method2(...) { ... computeAll(); ... }}
![Page 21: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/21.jpg)
Refactoring di più classi
class ComputationA { void method1(...) {...; step1(); step2(); step3(); ...}}
class ComputationB { void method2(...) {...; step1(); step2(); step3(); ...}}
• Codice duplicato su diverse classi
Continua…
![Page 22: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/22.jpg)
Refactoring di più classi
• Refactoring via ereditarietà
class Common { void commonSteps() { step1(); step2(); step3(); }}
class ComputationA extends Common { void method1(...) { ... ; commonSteps(); ... }}
class ComputationB extends Commom { void method2(...) { ... ; commonSteps(); ... }}
Continua…
![Page 23: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/23.jpg)
• Refactoring via aggregazione e delegation
Refactoring di più classi
class Helper { void commonSteps() { step1(); step2(); step3(); }}
class ComputationA{ Helper help; void method1(...) { ... ; help.commonSteps(); ... }}
class ComputationB{ Helper help; void method2(...) { ... ; help.commonSteps(); ... }}
![Page 24: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/24.jpg)
Refactoring – UML
ComputationA
method1()method2()
ComputationB
method1()method2()
Continua…
![Page 25: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/25.jpg)
• Refactoring via inheritance
Refactoring – UML
ComputationA
method1()method2()
ComputationB
method1()method2()
Common
commonSteps()
Continua…
![Page 26: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/26.jpg)
• Refactoring via aggregazione e delegation
Refactoring – UML
ComputationA
method1()method2()
ComputationB
method1()method2()
Helper
commonSteps()
helperhelper
![Page 27: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/27.jpg)
Una situazione più complessa
class ContextA { void method(...) { <codice comune 1>; stepA(); <codice comune 2>; }}
class ContextB { void method(...) { <codice comune 1>; stepB(); <codice comune 2>; }}
![Page 28: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/28.jpg)
Generalizziamo la soluzione?
class Common { commonCode1() { <codice comune 1> } commonCode2() { <codice comune 2> }}
class ContextA extends Common { void method(...) {commonCode1(); stepA(); commonCode2();}}
class ContextB { void method(...) {commonCode1(); stepB(); commonCode2();}}
Continua…
![Page 29: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/29.jpg)
Generalizziamo la soluzione?
• Uhm …
• se i due frammenti di codice comune sono strettamente dipendenti tra loro possibile che separarli generi errori rompe il flusso del controllo naturale peggiora la leggibilità del codice
• se i due frammenti sono parte dello stesso comando composto (ad esempio, un ciclo) non realizzabile
![Page 30: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/30.jpg)
Esempio: due Plotters
• Plotter per la funzione sin(x)
class PlotSin { . . .
protected void plotFunction(Graphics g) {
for (int px = 0; px < d.width; px++) {double x = (double)(px - xorigin) / (double)xratio;double y = Math.sin(x);int py = yorigin - (int) (y * yratio);g.fillOval(px - 1, py - 1, 3, 3);
}}
Continua…
![Page 31: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/31.jpg)
Esempio: due Plotters
• Plotter per la funzione cos(x)
class PlotCos { . . .
protected void plotFunction(Graphics g) {
for (int px = 0; px < d.width; px++) {double x = (double)(px - xorigin) / (double)xratio;double y = Math.cos(x);int py = yorigin - (int) (y * yratio);g.fillOval(px - 1, py - 1, 3, 3);
}}
![Page 32: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/32.jpg)
Una situazione più complessa
class ContextA { void method(...) { <codice comune 1>; stepA(); <codice comune 2>; }}
class ContextB { void method(...) { <codice comune 1>; stepB(); <codice comune 1>; }}
![Page 33: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/33.jpg)
Refactoring con il pattern Template
abstract class Common{ void methodoTemplate (...) { <codice comune 1>; metodoHook(...); <codice comune 2> } abstract void metodoHook();}
class ContextA extends Common { void metodoHook(...) { stepA(); }}
class ContextB extends Common { void metodoHook(...) { stepB(); }}
![Page 34: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/34.jpg)
Pattern Template
classe Concreta
methodHook1()methodHook2()
classe Generica
metodoTemplate()metodoHook1();metodoHook2();
. . . metodoHook1();. . . methdoHook2(). . .
![Page 35: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/35.jpg)
Esempio: progetto di animazioni
• Una applicazione del pattern template
• Fattorizza la logica di animazione in una classe astratta
• Lascia la definizione dell’immagine da animare alle sottoclassi concrete
• Vediamo la classe astratta Animator due classi concrete
•BouncingBall, DigitalClock
![Page 36: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/36.jpg)
Animatorpublic abstract class Animator
extends JComponent implements ActionListener { private int delay; private Timer T;
protected Animator(int delay) { this.delay = delay; setPreferredSize(new Dimension(getWidth(),getHeight())); T = new Timer(delay, this); } // schema di animazione: guidata dagli eventi del timer public void animate(){ T.start(); } public void actionPerformed(ActionEvent event){ repaint(); }
// metodo Hook public abstract void paintComponent(Graphics g);}
![Page 37: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/37.jpg)
Domanda
• Perché la classe Animator è abstract ?
• Quale è il metodo template?
• Quale è il metodo hook?
![Page 38: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/38.jpg)
Risposta
• E’ abstract perché non definisce il metodo paintComponent(), che gioca il ruolo di metodo hook in questa implementazione
• Il metodo template è actionPerformed() (che invoca paintComponent() via repaint())
![Page 39: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/39.jpg)
DigitalClock
public class DigitalClock extends Animator { private Font font = new Font("Monospaced", Font.BOLD, 48); private Color color = Color.GREEN;
private int width, height;
public DigitalClock(int delay, int width, int height) {
super(delay);this.width = width;this.height = height;
} . . .
Continua…
![Page 40: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/40.jpg)
DigitalClock
// metodo Hook public void paintComponent(Graphics g) { Calendar calendar = Calendar.getInstance(); int hour = calendar.get(Calendar.HOUR_OF_DAY); int minute = calendar.get(Calendar.MINUTE); int second = calendar.get(Calendar.SECOND);
String time = “ ” + (hour / 10) + (hour % 10) + ":" + (minute / 10) + (minute % 10) + ":" + (second / 10) + (second % 10);
g.setFont(font); g.setColor(color); g.drawString(time, 50, 150); }} // chiude DigitalClock
![Page 41: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/41.jpg)
DigitalClock
![Page 42: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/42.jpg)
BouncingBall
public class BouncingBall extends Animator { // la pallina private Ellipse2D.Double ball; private final int DIAM = 30;
// ampiezza dell'oscillazione private int jump;
// posizione corrente private int x, y;
// direzione dela prossima oscillazione 1 = dx, -1 = sx private int dir = 1;
Continua…
![Page 43: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/43.jpg)
BouncingBall
// costruttore public BouncingBall(int delay, int width, int height) {
super(delay);int lmargin = (int)(width * 0.1);int rmargin = (int)(width - DIAM - lmargin);jump = rmargin - lmargin;x = lmargin;y = (int)(height - DIAM) /3;ball = new Ellipse2D.Double(x,y,DIAM,DIAM);
}
Continua…
![Page 44: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/44.jpg)
BouncingBall
// metodo Hook public void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D)g;// calcola nuova posizionex = x + dir * jump; // inverti la direzionedir = -dir; ball.setFrame(x,y,DIAM,DIAM);g2.setColor(Color.BLUE);g2.fill(ball);
}} // fine BouncingBall
Continua…
![Page 45: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/45.jpg)
BouncingBall
![Page 46: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/46.jpg)
Esempio: progetto di un plotter
• Ancora applicazione del pattern template
• Fattorizza il comportamento grafico in una classe astratta
• Lascia la definizione della funzione da tracciare alle sottoclassi concrete
• Vediamo la classe astratta Plotter due classi concrete PlotSine, PlotCosine
Continua…
![Page 47: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/47.jpg)
Esempio: progetto di un plotter
![Page 48: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/48.jpg)
Plotter
public abstract class Plotter extends JFrame{ . . .
public Plotter(Dimension dim) { . . . }
public void paintComponent(Graphics g) { drawCoordinates(g); plotFunction(g); }
protected void drawCoordinates(Graphics g) { . . . }
. . .
Continua…
![Page 49: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/49.jpg)
Plotter
// metodo templateprotected void plotFunction(Graphics g) {
for (int px = 0; px < d.width; px++) { double x = (double)(px - xorigin) / (double)xratio; double y = func(x); int py = yorigin - (int) (y * yratio); g.fillOval(px - 1, py - 1, 3, 3);
}}
// metodo hookpublic abstract double func(double x);
} // end Plotter
![Page 50: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/50.jpg)
I plotter concreti
• Implementano il metodo hook
public class PlotSine extends Plotter {
public double func(double x) { return Math.sin(x);}
}
public class PlotCosine extends Plotter {
public double func(double x) { return Math.cos(x);
}}
![Page 51: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/51.jpg)
Un plotter multiplo
• Per il momento l’applicazione assegna ad ogni plotter una sola funzione
• Nuova funzionalità permettere il plotting di più funzioni
contemporaneamente
• Vincolo: ancora flessibilità: vogliamo disaccoppiare le funzioni
da tracciare dal plotter stesso
![Page 52: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/52.jpg)
Soluzione con Template
public class DoublePlotter {
// due metodi Hook public abstract double func1(double x);public abstract double func2(double x); ...
}
public class TriplePlotter {
// tre metodi hookpublic abstract double func1(double x);public abstract double func2(double x);public abstract double func3(double x);
...}
Continua…
![Page 53: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/53.jpg)
Soluzione con Template ?
• Poco elegante: una classe plotter per ciascun numero di funzioni da tracciare
• Poco flessibile: dobbiamo restringerci ad un numero fissato di funzioni, mentre vorremmo definire un MultiPlotter generico
• Troppi poco …
![Page 54: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/54.jpg)
Soluzione con Strategy
• come Template disaccoppia le funzioni da tracciare dal plotter
• ma invece di rappresentare ogni funzione come un metodo, rappresenta come un oggetto
![Page 55: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/55.jpg)
Oggetti Function
interface Function{ double apply(double x);}public class Sine implements Function{ public double apply(double x) { return Math.sin(x); }}public class Cosine implements Function { public double apply(double x) { return Math.cos(x); }}
• Sfruttiamo dynamic dispatch per invocare il metodo apply() corretto
![Page 56: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/56.jpg)
Plotter
• Vediamo le conseguenze di questa idea nel progetto del plotter
![Page 57: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/57.jpg)
Plotter
import javax.swing.*;
public abstract class Plotter extends JFrame {
. . . private Function fun;
public void paint(Graphics g) { drawCoordinates(g); plotFunction(g);
}
public Plotter (Dimension dim) { . . . }
. . . Continua…
![Page 58: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/58.jpg)
Plotter
protected void plotFunction(Graphics g) {
for (int px = 0; px < d.width; px++) { double x = (double)(px - xorigin) / (double)xratio; double y = fun.apply(x); int py = yorigin - (int) (y * yratio); g.fillOval(px - 1, py - 1, 3, 3);
}}
} // end Plotter
![Page 59: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/59.jpg)
Pattern Strategy
StrategyyA
metodoHook()
Strategy
metodoHook()
. . . strategy.metodoHook();. . .
Contesto
metodoDiContesto()
stragegy
StrategyB
metodoHook()
![Page 60: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/60.jpg)
Pattern Strategy su Plotter
Sine
apply()
Function
apply()
. . . fun.apply();. . .
Plotter
plotFunction()
fun
Cosine
apply()
![Page 61: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/61.jpg)
MultiPlotter
Continua…
• Ora generalizziamo per creare il plotter multiplo
![Page 62: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/62.jpg)
MultiPlotterimport javax.swing.*;public abstract class MultiPlotter extends JFrame {
. . . private List<Function> fns = new ArrayList<Function>;private List<Color> colors = new ArrayList<Color>;
public void paint(Graphics g) { drawCoordinates(g); plotFunction(g);
}
public MultiPlotter (Dimension dim) { . . . }
public void addFunction(Function f, Color c) { fns.add(f); colors.add(c); } . . .
Continua…
![Page 63: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/63.jpg)
MultiPlotter
...protected void plotFunction(Graphics g) { for (int i = 0; i < fns.size(); i++) {
if (fns.get(i) != null) { Color c = colors.tet(i); if (c != null) g.setColor(c); else g.setColor(Color.black); for (int px = 0; px < d.width; px++) { double x = (double) (px - xorigin) / (double) xratio; double y = fns.get(i).apply(x); int py = yorigin - (int) (y * yratio); g.fillOval(px - 1, py - 1, 3, 3);
}}} }
![Page 64: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/64.jpg)
Classe concreta PlotSineCosine
public class PlotSineCosine extends MultiPlotter {
public PlotSineCosine() { // ricordate: Sine e Cosine implementano Function addFunction(new Sine(), Color.green); addFunction(new Cosine(), Color.blue);
}}
![Page 65: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/65.jpg)
Caso di studio: animazione di algoritmi
• La struttura di animazione generica vista negli esempi del DigitalClock e BouncingBall precedenza non è sempre adeguata
• Nell’animazione di un algoritmo animazione deve essere gestibile dall’algoritmo chiamata a repaint(), deve essere controllata
dell’esecuzione, non ad istanti stabiliti dall’esterno
• Vogliamo comunque disaccoppiamento tra algoritmo e la struttura di animazione
![Page 66: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/66.jpg)
Soluzione 1 – Template
SortAnimator
algorithm() sort()
AlgorithmAninator
animate()algorithm() . . .
algorithm(). . .
scramble()sort();. . .
BubbleSortAnimator
sort()
QuickSortAnimator
sort()
![Page 67: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/67.jpg)
AlgorithmAnimator
public abstract class AlgorithmAnimator extends JComponent { public AlgorithmAnimator(int d) { delay = d; }
// metodi template: animate() & pause() public void animate() { algorithm(); }
final protected void pause() {try { Thread.currentThread().sleep(delay); } catch (InterruptedException e) { }repaint();
} // metodi hook: paintComponent() & algorithm() abstract protected void algorithm();
private int delay;}
![Page 68: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/68.jpg)
SortAnimator
public class SortAnimator extends AlgorithmAnimator {
// l’array da ordinare protected int arr[]; private void swap(int a[], int i, int j) { int T; T = a[i]; a[i] = a[j]; a[j] = T; }
protected void scramble() { arr = new int[getPreferredSize().height / 6]; for (int i = arr.length; --i >= 0;) { arr[i] = (int)(i * Math.random());}
}
![Page 69: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/69.jpg)
SortAnimator
// metodo hook protected void paintComponent(Graphics g) {
Dimension d = getSize(); g.setColor(Color.BLACK);g.fillRect(0, 0, d.width, d.height); g.setColor(Color.GREEN);int y = d.height - 10; double f = d.width / (double) arr.length; for (int i = arr.length; --i >= 0; y -= 5) { g.fillRect(0, y, (int)(arr[i] * f), 3);}
}
![Page 70: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/70.jpg)
SortAnimator
// metodo hook final public void algorithm() { scramble(); JOptionPane.showMessageDialog(this, "Start animation"); sort(arr); JOptionPane.showMessageDialog(this,"Done! "); } // nuovo template protected abstract void sort(int[] a);
} // Chiude SortAnimator
![Page 71: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/71.jpg)
BubbleSortAnimator
public class BubbleSortAnimator extends SortAnimator { public BubbleSortAnimator(int delay) {
super(delay); }
// override del metodo nella superclasse protected void sort(int[] a) {
for (int i = a.length; --i >= 0; ) for (int j = 0; j < i; j++) {
if (a[j] > a[j+1]) swap(a, j, j + 1); pause();
} }}
![Page 72: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/72.jpg)
Valutazione
• Implementazione molto semplice
• Supporta diversi algoritmi
• Ma …• La classe SortAnimator è poco coesa• fornisce metodi legati ad aspetti algoritmici e di
visualizzazione
• Separare i due aspetti aumenta la flessibilità • nuova soluzione
![Page 73: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/73.jpg)
Soluzione 2 – Strategy
SortAnimator
animate()
AlgorithmAninator
animate()pause()
. . . animator.pause(). . .
sorter.sort(). . .
BubbleSort
sort()
QuinckSort
sort()
SortingAlgorithm
sort()sorter
animator
![Page 74: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/74.jpg)
AlgorithmAnimator
public abstract class AlgorithmAnimator extends JComponent { private int delay;
public AlgorithmAnimator(int delay){this.delay = delay;}
// template degenere, no hooks public abstract void animate();
final protected void pause() {try { Thread.currentThread().sleep(delay); } catch (InterruptedException e) { }repaint();
}}
![Page 75: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/75.jpg)
SortAnimator
public class SortAnimator extends AlgorithmAnimator {
// l’array da ordinare private int arr[];
// l'algoritmo che esegue il sorting protected SortingAlgorithm sorter;
protected SortAnimator(int delay, SortingAlgorithm sorter) {
super(delay); this.sorter = sorter; sorter.setAnimator(this);
}
![Page 76: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/76.jpg)
SortAnimator
public void animate() { scramble(); JOptionPane.showMessageDialog(this, "Start"); sorter.sort(arr); JOptionPane.showMessageDialog(this,"Done! "); }
// metodi scramble e paintComponent invariati . . . }
![Page 77: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/77.jpg)
SortingAlgorithm
public abstract class SortingAlgorithm {
protected SortAnimator animator;
public setAnimator(SortAnimator animator) {this.animator = animator;
}
public abstract void sort(int[] a);
protected void swap(int a[], int i, int j) { . . . }}
![Page 78: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/78.jpg)
BubbleSort
public class BubbleSort extends SortingAlgorithm { public void sort(int[] a) {
for (int i = a.length; --i >= 0; ) for (int j = 0; j < i; j++) {
if (a[j] > a[j+1]) swap(a, j, j + 1);// accesso protected al
// campo della superclasse animator.pause();
} }}
![Page 79: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/79.jpg)
Valutazione
• La struttura della classe SortAnimator è migliore
• Ma … ci sono ulteriori misure per migliorare la coesione il metodo di visualizzazione dell’array può essere
separato dall’algoritmo e dal meccanismo di animazione
più flessibile
![Page 80: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/80.jpg)
Soluzione 3 – Strategy2
SortAnimator
animate()
AlgorithmAninator
animate()pause()
BubbleSort
sort()
QuinckSort
sort()
SortingAlgorithm
sort()
theDisplayDisplayMethod
display()
DisplayMethod
display()
DisplayMethod
display()
ConfigSortAnimator
![Page 81: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/81.jpg)
Soluzione 3 – Strategy2
• Classi AlgorithmAnimator, Sorting Animator
• Gerarchia SortingAlgorithm
• Invariate
![Page 82: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/82.jpg)
ConfigurableSortAnimator
public class ConfigurableSortAnimator extends SortAnimator{ // il visualizzatore vero e proprio protected DisplayMethod theDisplay;
protected ConfigurableSortAnimator(int delay, SortingAlgorithm sorter, DisplayMethod display) {
super(delay,sorter);theDisplay = display;
}
protected void paintComponent(Graphics g) {Dimension d = getSize(); int[] a = getArray();theDisplay.display(a,d,g);
}}
![Page 83: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/83.jpg)
DisplayMethod
public interface DisplayMethod{ public void display(int[] arr, Dimension d, Graphics g);}
public class VDisplay implements DisplayMethod { public void display(int[] arr, Dimension d, Graphics g) {
. . . }}
![Page 84: Tecniche di Progetto (a.k.a. Design Patterns). Progettazione Object-Oriented Passi della prassi Definizione delle classi Determinazione delle responsabilità](https://reader036.vdocuments.site/reader036/viewer/2022062418/5542eb59497959361e8c427b/html5/thumbnails/84.jpg)
Frameworks
• Tipicamente: insieme di classi astratte ed interfacce
• Forniscono applicazioni semi-complete
• Da specializzare
• Progettate cercando di garantire i principi di astrazione e di favorire il riuso mediante l’applicazione di design patterns come quelli che abbiamo visto