Interfacce. Interfacce come strumento di progetto Scelta delle classi di un progetto Criteri di...

41
Interfacce

Transcript of Interfacce. Interfacce come strumento di progetto Scelta delle classi di un progetto Criteri di...

Page 1: Interfacce. Interfacce come strumento di progetto Scelta delle classi di un progetto Criteri di coesione e accoppiamento Interfacce e riuso di codice.

Interfacce

Page 2: Interfacce. Interfacce come strumento di progetto Scelta delle classi di un progetto Criteri di coesione e accoppiamento Interfacce e riuso di codice.

• Interfacce come strumento di progetto Scelta delle classi di un progetto Criteri di coesione e accoppiamento Interfacce e riuso di codice

Page 3: Interfacce. Interfacce come strumento di progetto Scelta delle classi di un progetto Criteri di coesione e accoppiamento Interfacce e riuso di codice.

Organizzazione di una classe

public class ClassTemplate {

// costanti pubbliche

// costruttori pubblici

// metodi “accessors” pubblici

// metodi “mutators” pubblici

// campi privati

// classi interne e metodi ausiliari privati

}

Continua…

Page 4: Interfacce. Interfacce come strumento di progetto Scelta delle classi di un progetto Criteri di coesione e accoppiamento Interfacce e riuso di codice.

Organizzazione di una classe

• Visibilità dei campi: evitare campi pubblici Quando necessario, definite metodi per accedere e

modificare i campi

• Completezza dell’interfaccia pubblica Assicuratevi che l’interfaccia pubblica fornisca le

funzionalità necessarie per un utilizzo naturale ed efficace delle istanze

• Documentate il codice Non solo commenti (vedremo …)

Page 5: Interfacce. Interfacce come strumento di progetto Scelta delle classi di un progetto Criteri di coesione e accoppiamento Interfacce e riuso di codice.

Classi di un progetto• Una classe dovrebbe rappresentare un

concetto singolo, oppure un insieme di valori ben caratterizzato (un tipo)

• Concetti/tipi in matematica:Point, Rectangle, ..., Set, List, ...

• Concetti/tipi nella vita reale BankAccount, CashRegister, ...

Continua…

Page 6: Interfacce. Interfacce come strumento di progetto Scelta delle classi di un progetto Criteri di coesione e accoppiamento Interfacce e riuso di codice.

Classi di un progetto

• Una classe può anche identificare un insieme di “attori” oggetti che offrono un insieme di funzionalità

Scanner, RandomNumberGenerator

• Una classe può anche agire da contenitore di metodi e campi static (quindi una classe

senza istanze)

Math inizializzatore della computazione (mediante il main)

Page 7: Interfacce. Interfacce come strumento di progetto Scelta delle classi di un progetto Criteri di coesione e accoppiamento Interfacce e riuso di codice.

Coesione

• Una classe dovrebbe rappresentare un solo concetto

• L’interfaccia pubblica di una classe è coesa se tutte le sue componenti sono relative al concetto che la classe rappresenta

Continua…

Page 8: Interfacce. Interfacce come strumento di progetto Scelta delle classi di un progetto Criteri di coesione e accoppiamento Interfacce e riuso di codice.

Coesione

• Questo è un esempio di classe non coesa …

• Perché?

public class CashRegister{ public void enterPayment(int dollars, int quarters, int dimes, int nickels, int pennies) . . . public static final double NICKEL_VALUE = 0.05; public static final double DIME_VALUE = 0.1; public static final double QUARTER_VALUE = 0.25; . . .}

Continua…

Page 9: Interfacce. Interfacce come strumento di progetto Scelta delle classi di un progetto Criteri di coesione e accoppiamento Interfacce e riuso di codice.

Coesione• CashRegister coinvolge due concetti:

Registratore di cassa, monete

• Soluzione alternativa: due classi

public class Coin{ public Coin(double aValue, String aName){ . . . } public String getName(){ . . . } . . .}public class CashRegister{ public void enterPayment(Coin... coins) { . . . } . . .}

vararg

Page 10: Interfacce. Interfacce come strumento di progetto Scelta delle classi di un progetto Criteri di coesione e accoppiamento Interfacce e riuso di codice.

Accoppiamento (Coupling )• Una classe dipende da un’altra classe se

utilizza oggetti di quella classe CashRegister dipende da Coin per il calcolo della

somma del pagamento Coin non dipende CashRegister

Continua…

Page 11: Interfacce. Interfacce come strumento di progetto Scelta delle classi di un progetto Criteri di coesione e accoppiamento Interfacce e riuso di codice.

UML

• Per visualizzare le relazioni tra classi utilizziamo diagrammi

• UML: Unified Modeling Language.

• Notazione standard per l’analisi ed il progetto di applicazioni software

Page 12: Interfacce. Interfacce come strumento di progetto Scelta delle classi di un progetto Criteri di coesione e accoppiamento Interfacce e riuso di codice.

Gradi di accoppiamento• Alto grado di accoppiamento implica molte

dipendenze tra classi

• Basso grado di accoppiamenento facilita manutenibilità in caso di modifica delle componenti (della loro interfaccia esterna)

Continua…

Page 13: Interfacce. Interfacce come strumento di progetto Scelta delle classi di un progetto Criteri di coesione e accoppiamento Interfacce e riuso di codice.

Gradi di accoppiamento

• Vedremo tecniche per bilanciare correttamente il grado di accoppiamento

Page 14: Interfacce. Interfacce come strumento di progetto Scelta delle classi di un progetto Criteri di coesione e accoppiamento Interfacce e riuso di codice.

Interfacce

• L’impiego di tipi interfaccia nel progetto di una applicazione rende il codice flessibile e robusto favorisce il riuso di codice permette di controllare il grado di accoppiamento tra

le componenti del progetto

• Esempio: definiamo una classe DataSet che permette di condurre alcune semplici analisi su un insieme di dati numerici calcolo della media calcolo del valore massimo Continua…

Page 15: Interfacce. Interfacce come strumento di progetto Scelta delle classi di un progetto Criteri di coesione e accoppiamento Interfacce e riuso di codice.

DataSetpublic class DataSet { public void add(double x) { sum = sum + x; if (count == 0 || maximum < x) maximum = x; count++; } public double getMaximum() { return (count>0)? maximum : Double.NaN; }

public double average() { return (count>0)? sum/count : Double.NaN; } private double sum; private double maximum; private int count; }

Page 16: Interfacce. Interfacce come strumento di progetto Scelta delle classi di un progetto Criteri di coesione e accoppiamento Interfacce e riuso di codice.

Interfacce

• Ora supponiamo di voler condurre le stesse analisi su un insieme di conti bancari per

• tracciare la media degli importi del saldo• calcolare il conto con il saldo massimo.

monete per • calcolare l taglio medio delle monete• determinare il taglio massimo

• La struttura della classe è sempre la stessa, ma il codice cambia …

Continua…

Page 17: Interfacce. Interfacce come strumento di progetto Scelta delle classi di un progetto Criteri di coesione e accoppiamento Interfacce e riuso di codice.

DataSet – versione per BankAccount

public class DataSet { public void add(BankAccount x) { sum = sum + x.getBalance(); if (count == 0 || maximum.getBalance() < x.getBalance()) maximum = x; count++; } public BankAccount getMaximum() { return maximum; } public double average() {return (count>0)? sum/count : Double.NaN; } private double sum; private BankAccount maximum; private int count; }

Page 18: Interfacce. Interfacce come strumento di progetto Scelta delle classi di un progetto Criteri di coesione e accoppiamento Interfacce e riuso di codice.

DataSet – versione per Coinpublic class DataSet { public void add(Coin x) { sum = sum + x.getValue(); if (count == 0 || maximum.getValue() < x.getValue()) maximum = x; count++; }

public Coin getMaximum() { return maximum; } public double average() {return (count>0)? sum/count : Double.NaN; } private double sum; private Coin maximum; private int count; }

Page 19: Interfacce. Interfacce come strumento di progetto Scelta delle classi di un progetto Criteri di coesione e accoppiamento Interfacce e riuso di codice.

Interfacce riuso di codice

• Il meccanismo di analisi dei dati è sempre lo stesso; la differenza è solo nel metodo che estrae i valori

• E se le diverse classi si uniformassero nell’uso di uno stesso metodo, getMeasure() per fornire la misura?

• In quel caso potremmo definire una sola versione di DataSet con un metodo add() come il seguente

Continua…

sum = sum + x.getMeasure(); if (count == 0 || maximum.getMeasure() < x.getMeasure()) maximum = x; count++;

Continua…

Page 20: Interfacce. Interfacce come strumento di progetto Scelta delle classi di un progetto Criteri di coesione e accoppiamento Interfacce e riuso di codice.

Interfacce riuso di codice

• Quale è il tipo della variabile x a questo punto?

• Idea: il tipo di una qualunque classe che fornisca un metodo getMeasure

• In Java usiamo tipi interfaccia

• Una dichiarazione di interfaccia include tutti i metodi (le loro firme) che intendiamo attribuire al tipo interfaccia corrispondente

public interface Measurable { double getMeasure(); }

Page 21: Interfacce. Interfacce come strumento di progetto Scelta delle classi di un progetto Criteri di coesione e accoppiamento Interfacce e riuso di codice.

DataSet – versione generica

public class DataSet{ public void add(Measurable x) { sum = sum + x.getMeasure(); if (count == 0 || maximum.getMeasure() < x.getMeasure()) maximum = x; count++; } public Measurable getMaximum() { return maximum; } public double average() { return sum/count; } private double sum; private Measurable maximum; private int count; }

Page 22: Interfacce. Interfacce come strumento di progetto Scelta delle classi di un progetto Criteri di coesione e accoppiamento Interfacce e riuso di codice.

Classi vs. Interfacce

• Un tipo interfaccia è simile ad un tipo classe, ma ci sono molte differenze importanti:

• I metodi (tutti) dell’interfaccia sono “astratti” L’interfaccia non definisce una implementazione

• Tutti i metodi di una interfaccia sono automaticamente pubblici

• Una interfaccia non ha campi (mentre può avere campi statici, ovvero costanti)

Page 23: Interfacce. Interfacce come strumento di progetto Scelta delle classi di un progetto Criteri di coesione e accoppiamento Interfacce e riuso di codice.

Classi implementano Interfacce• La keyword implements indica che una classe

implementa una interfaccia

• Una classe può implementare più interfacce La classe deve implementare tutti i metodi di tutte le

interfacce che implementa tutti questi metodi devono essere public nella classe

public class BankAccount implements Measurable { public double getMeasure() { return balance; } // altri metodi, campi e quant’altro ... }

Continua…

Page 24: Interfacce. Interfacce come strumento di progetto Scelta delle classi di un progetto Criteri di coesione e accoppiamento Interfacce e riuso di codice.

Classi implementano Interfacce

• Measurable Coins

public class Coin implements Measurable { public double getMeasure() { return value; } // . . . }

Page 25: Interfacce. Interfacce come strumento di progetto Scelta delle classi di un progetto Criteri di coesione e accoppiamento Interfacce e riuso di codice.

Diagrammi UML

• Notazione: Le interfacce sono rappresentate utilizzando

• la tag «interface» associata al nome• oppure indicando il nome in corsivo• La relazione tra una interfaccia ed una classe che

la implementa è rappresentata da una freccia tratteggiaga (dalla classe all’interfaccia)

Notazione simile alla dipendenza: cambia la punta della freccia

Continua…

Page 26: Interfacce. Interfacce come strumento di progetto Scelta delle classi di un progetto Criteri di coesione e accoppiamento Interfacce e riuso di codice.

Diagramma UML per l’esempio

dipende

implementa

Page 27: Interfacce. Interfacce come strumento di progetto Scelta delle classi di un progetto Criteri di coesione e accoppiamento Interfacce e riuso di codice.

Diagrammi UML

• L’impiego di interfacce riduce il numero di classi ed il grado di accoppiamento tra le classi

• Notate infatti che DataSet è disaccoppiata da BankAccount e Coin

• Possiamo liberamente modificare le classi basta che implementino correttamente l’interfaccia

Page 28: Interfacce. Interfacce come strumento di progetto Scelta delle classi di un progetto Criteri di coesione e accoppiamento Interfacce e riuso di codice.

Sintassi: definizione di interfaccia

public interface InterfaceName { // firme e contratti per i metodi }

Esempio: public interface Measurable { double getMeasure(); }

Scopo:Definire le firme ed i contratti per i metodi di un tipo interfaccia. Tutti i metodi sono automaticamente pubblici.

Page 29: Interfacce. Interfacce come strumento di progetto Scelta delle classi di un progetto Criteri di coesione e accoppiamento Interfacce e riuso di codice.

Sintassi: dichiarazione di classe

 public class ClassName implements InterfaceName, InterfaceName, ... { // ... }

Esempio: public class BankAccount implements Measurable { //... public double getMeasure() { // Method implementation } }

Scopo:Fornire una implementazione per il tipo interfaccia

Page 30: Interfacce. Interfacce come strumento di progetto Scelta delle classi di un progetto Criteri di coesione e accoppiamento Interfacce e riuso di codice.

File DataSetTester.java01: /**02: This program tests the DataSet class.03: */04: public class DataSetTester05: {06: public static void main(String[] args)07: {08: DataSet bankData = new DataSet();09: 10: bankData.add(new BankAccount(0));11: bankData.add(new BankAccount(10000));12: bankData.add(new BankAccount(2000));13: 14: System.out.println("Average balance = " 15: + bankData.getAverage());16: Measurable max = bankData.getMaximum();17: System.out.println("Highest balance = " 18: + max.getMeasure()); Continua…

Page 31: Interfacce. Interfacce come strumento di progetto Scelta delle classi di un progetto Criteri di coesione e accoppiamento Interfacce e riuso di codice.

File DataSetTester.java

19: 20: DataSet coinData = new DataSet();21: 22: coinData.add(new Coin(0.25, "quarter"));23: coinData.add(new Coin(0.1, "dime"));24: coinData.add(new Coin(0.05, "nickel"));25: 26: System.out.println("Average coin value = " 27: + coinData.getAverage());28: max = coinData.getMaximum();29: System.out.println("Highest coin value = " 30: + max.getMeasure());31: }32: }

Continua…

Page 32: Interfacce. Interfacce come strumento di progetto Scelta delle classi di un progetto Criteri di coesione e accoppiamento Interfacce e riuso di codice.

File DataSetTester.java

Average balance = 4000.0 Highest balance = 10000.0 Average coin value = 0.13333333333333333 Highest coin value = 0.25

Output:

Page 33: Interfacce. Interfacce come strumento di progetto Scelta delle classi di un progetto Criteri di coesione e accoppiamento Interfacce e riuso di codice.

Domande

• Vogliamo utilizzare la classe DataSet per trovare l’istanza di una classe Country con la popolazione maggiore in un insieme. Quali condizioni deve soddisfare la classe Country?

• Cosa c’è di sbagliato nel seguente codice?

public void add(Object x){ sum = sum + x.getMeasure(); if (count == 0 || maximum.getMeasure() < x.getMeasure()) maximum = x; count++; }

Page 34: Interfacce. Interfacce come strumento di progetto Scelta delle classi di un progetto Criteri di coesione e accoppiamento Interfacce e riuso di codice.

Risposte

• Deve implementare l’interfaccia Measurable ed il suo metodo getMeasure() deve restituire il valore della popolazione

• La classe Object non ha un metodo getMeasure(), che viene invocato all’interno del metodo add()

Page 35: Interfacce. Interfacce come strumento di progetto Scelta delle classi di un progetto Criteri di coesione e accoppiamento Interfacce e riuso di codice.

Polimorfismo – dynamic dispatch

• Dynamic dispatch: Il metodo da invocare per rispondere ad un

messaggio è deciso a tempo di esecuzione

Page 36: Interfacce. Interfacce come strumento di progetto Scelta delle classi di un progetto Criteri di coesione e accoppiamento Interfacce e riuso di codice.

Dynamic dispatch in GWin

class GWin { . . . private ArrayList<Shape> shapes; . . . public void paint() {

// disegna tutte le componenti della GWin // il metodo invocato effettivamente da ogni

// messaggio s.draw(g) dipende dalla classe // di cui s è istanza ed è deciso a runtime

for (Shape s:shapes) s.draw(g); } . . . . }

Page 37: Interfacce. Interfacce come strumento di progetto Scelta delle classi di un progetto Criteri di coesione e accoppiamento Interfacce e riuso di codice.

Dynamic dispatch vs overloading

• Dynamic dispatch: Il metodo da invocare per rispondere ad un

messaggio è deciso a tempo di esecuzione

• Notiamo bene Il metodo da invocare è deciso a runtime il compilatore decide se esiste un metodo da invocare

• Overloading: Nel caso esista più di un metodo, il compilatore

decide staticamente il tipo del metodo da invocare

Page 38: Interfacce. Interfacce come strumento di progetto Scelta delle classi di un progetto Criteri di coesione e accoppiamento Interfacce e riuso di codice.

Dynamic dispatch vs overloading

interface I { public String m(boolean b); public String m(double d); } class A implements I { public String m(boolean b) { return “A.m(boolean)”; } public String m(double d) { return “A.m(double)”; } }

class B implements I { public String m(boolean b) { return “B.m(boolean)”; } public String m(double d) { return “B.m(double)”; } }

Page 39: Interfacce. Interfacce come strumento di progetto Scelta delle classi di un progetto Criteri di coesione e accoppiamento Interfacce e riuso di codice.

Dynamic dispatch vs overloading

class Client { public void static show(I x) { // tipo del metodo invocato = m(boolean) // deciso dal compilatore staticamente // metodo invocato deciso dinamicamente // in funzione del tipo dell’argomento // passato per x

System.out.println( x.m(false) ); } }

Page 40: Interfacce. Interfacce come strumento di progetto Scelta delle classi di un progetto Criteri di coesione e accoppiamento Interfacce e riuso di codice.

Domanda

• Che cosa hanno in comune i meccanismi di overloading e di dynamic dispatch? In cosa sono diversi?

Page 41: Interfacce. Interfacce come strumento di progetto Scelta delle classi di un progetto Criteri di coesione e accoppiamento Interfacce e riuso di codice.

• Entrambi i meccanismi contribuiscono a decidono quale metodo eseguire in risposta ad un messaggio, ma• Nell’overloading scelta è relativa al tipo del metodo,

ed è fatta in compilazione guardando il tipo dei parametri

• Nel dynamic dispatch la scelta è relativa al corpo del metodo, ed è fatta in esecuzione guardando il tipo dell’oggetto che riceve il messaggio

Risposta