© 2008 WS (WebScience srl) – All rights reserved
WS Tech workshop
Software Construction
© 2008 WS (WebScience srl) – All rights reserved
Indice
WS © | 2
• La costruzione del software
• Il design nella costruzione
• Classi che funzionano
• Routine di qualità
• Programmazione difensiva
• La potenza delle variabili
• Usare i condizionali
• Controllare i loop
• Ottimizzare con giudizio
© 2008 WS (WebScience srl) – All rights reserved
Cosa è la costruzione del software
WS © | 3
© 2008 WS (WebScience srl) – All rights reserved
Cosa è la costruzione del software
WS © | 4
Definizione problema e dominio
Definizione architettura
Analisi e specifica requisiti
Design
Test di unitàTest funzionali
Test di integrazione
Integrazione
Manutenzione
Scrittura codice
Debugging
Refactoring
© 2008 WS (WebScience srl) – All rights reserved
Cosa è la costruzione del software
WS © | 5
Definizione problema e dominio
Definizione architettura
Analisi e specifica requisiti
Design
Test di unitàTest funzionali
Test di integrazione
Integrazione
Manutenzione
Scrittura codice
Debugging
Refactoring
© 2008 WS (WebScience srl) – All rights reserved
Perchè è importante
• Include gran parte dello sviluppo del progetto
• Permette di aumentare di molto la produttività
• Il codice è l'unica fonte certa di documentazione
• E' l'unica attività che verrà svolta sicuramente
WS © | 6
© 2008 WS (WebScience srl) – All rights reserved
Perchè è importante
“Good code is its own best documentation. As you're about to add a
comment, ask yourself, "How can I improve the code so that this
comment isn't needed?"”
~ Steve McConnell
WS © | 7
int i;main(){for(;i["]<i;++i){--i;}"];read('-'-'-',i+++"hell\o, world!\n",'/'/'/'));}read(j,i,p){write(j/p+p,i---j,i/i);}
© 2008 WS (WebScience srl) – All rights reserved
Perchè è importante
“Any fool can write code that a computer can understand. Good
programmers write code that humans can understand”
~ Martin Fowler
WS © | 8
.model tiny
.code org 100hmov dx,al mov ah,9 int 21h xor ah,ah int 16h mov bl,al mov dl,al mov ah,02h int 21h
© 2008 WS (WebScience srl) – All rights reserved
Perchè è importante
WS © | 9
“Always code as if the guy who ends up maintaining your
code will be a violent psychopath who knows where you
live”
~ Martin Golding
© 2008 WS (WebScience srl) – All rights reserved
Il design nella costruzione del software
WS © | 10
© 2008 WS (WebScience srl) – All rights reserved
Gestire la complessità
WS © | 11
“Entia non sunt multiplicanda praeter necessitatem”
~ William of Ockham
© 2008 WS (WebScience srl) – All rights reserved
Gestire la complessità
WS © | 12
• Minimizzare la complessità accidentale
• Minimizzare la quantità di complessità essenziale
© 2008 WS (WebScience srl) – All rights reserved
Astrazioni consistenti
WS © | 13
© 2008 WS (WebScience srl) – All rights reserved
Incapsulare i dettagli
WS © | 14
© 2008 WS (WebScience srl) – All rights reserved
Ereditare le proprietà
WS © | 15
© 2008 WS (WebScience srl) – All rights reserved
Nascondere i segreti
WS © | 16
© 2008 WS (WebScience srl) – All rights reserved
Anticipare i cambiamenti
WS © | 17
© 2008 WS (WebScience srl) – All rights reserved
Accoppiamento debole
WS © | 18
© 2008 WS (WebScience srl) – All rights reserved
Design pattern
WS © | 19
© 2008 WS (WebScience srl) – All rights reserved
Classi che funzionano
WS © | 20
© 2008 WS (WebScience srl) – All rights reserved
Mantenere una buona astrazione
WS © | 21
public interface ArchivioDipendenti {
void aggiungiDipendente(Dipendente dipendente);
void rimuoviDipendente(Dipendente dipendente);
Dipendente primoElemento();
Dipendente prossimoElemento();
ReportDipendenti creaReport();
void inizializzaDatiStipendi();
long calcolaStipendio(Dipendente dipendente);
}
© 2008 WS (WebScience srl) – All rights reserved
Mantenere una buona astrazione
• Unica astrazione derivata dal dominio
• Un solo livello di astrazione
• Le informazioni scollegate restano all'esterno
• L'interfaccia è più programmatica che semantica
WS © | 22
© 2008 WS (WebScience srl) – All rights reserved
Mantenere un buon incapsulamento
WS © | 23
public class Dipendente {
protected String nome;
protected String cognome;
protected Date nascita;
public Dipendente(String nome, String cognome, ListaDate date) { init();
...
nascita = listaDate.getDettaglio(nome,cognome).getData();
}
public void init() {
...
}
}
© 2008 WS (WebScience srl) – All rights reserved
Mantenere un buon incapsulamento
WS © | 24
• Livello di accesso minimo
• L'interfaccia non espone dettagli implementativi
• Nessuna assunzione sull'utilizzo dell'interfaccia
• Riduzione della collaborazione con altre classi al minimo
© 2008 WS (WebScience srl) – All rights reserved
Preferire la composizione all'ereditarietà
WS © | 25
public class CountingHashSet<E> extends HashSet<E> {
private int addCount;
public boolean add(E e) {
addCount++;
return super.add(e);
}
public boolean addAll(Collection<? Extends E> c) {
addCount+=c.size();
return super.addAll(c);
}
public int getAddCount() {
return addCount;
}
}
© 2008 WS (WebScience srl) – All rights reserved
Preferire la composizione all'ereditarietà
WS © | 26
• La forma principale di associazione è has-a
• Al massimo 7 membri
• Ereditarietà solo per associazioni is-a naturali
• Progettare per l'ereditarietà oppure proibirla
• Preferire il polimorfismo al controllo del tipo
© 2008 WS (WebScience srl) – All rights reserved
Routine di qualità
WS © | 27
© 2008 WS (WebScience srl) – All rights reserved
Coesione funzionale
WS © | 28
public void calc(DatoTab tab, Color col, int col1, int col2,
String dbAdr, String st) {
int i;
for (i = 0;i<100;i++) {
tab.getSomma().cont[i] = ++i;
}
modDB(tab, dbAdr);
if (col1 == 1 || col2 == 1) {
setColor(col);
} else {
setColor(Color.RED);
st = “n/a”;
}
}
© 2008 WS (WebScience srl) – All rights reserved
Coesione funzionale
WS © | 29
• Esegue un singolo compito
• Le istruzioni contenute sono tutte collegate
• Il nome esprime tutto e solo ciò che la routine fa
• Naming convention consistente
© 2008 WS (WebScience srl) – All rights reserved
Usare al meglio i parametri
WS © | 30
public long getTotale(int inCol, int colSum1, int colSum3, int
colSum2, int colSum4, int colMol, int ColAdd, int colExp) {
inCol = colMol * colSum4 + colSum2;
if (inCol == 10) {
inCol = 1;
} else {
inCol = colSum3^colExp;
}
return inCol;
}
© 2008 WS (WebScience srl) – All rights reserved
Usare al meglio i parametri
WS © | 31
• Ordine chiaro e consistente
• Nessun effetto collaterale
• Non sfruttare i parametri come variabili di lavoro locali
• Al massimo 5 parametri
• La granularità dei parametri rispetta il livello di astrazione
© 2008 WS (WebScience srl) – All rights reserved
Programmazione difensiva
WS © | 32
© 2008 WS (WebScience srl) – All rights reserved
Validazione e asserzioni
WS © | 33
public class Calcolatore {
public calcola(Operatore operatore, int op1, int op2) {
assert (++op1>=0 && ++op2>=0);
switch (operatore) {
case molt: moltiplica(op1, op2);
case div: dividi(op1, op2);
}
}
private int dividi(int numeratore, int denominatore) {
return numeratore/denominatore;
}
...
}
© 2008 WS (WebScience srl) – All rights reserved
Validazione e asserzioni
WS © | 34
• Validazione di tutti i dati in ingresso
• Asserzioni per le condizioni impossibili
• Asserzioni per precondizioni e postcondizioni
• Un'asserzione non esegue codice e non gestisce errori
© 2008 WS (WebScience srl) – All rights reserved
Gestire le eccezioni
WS © | 35
public class Dipendente {
private String codiceFiscale;
private String nome;
public Dipendente(String codiceFiscale) throws SQLExecption
nome = leggiDipendenteDB(codiceFiscale);
}
public void setNome(String nome){
try{
scriviDipendenteDB(codiceFiscale, nome);
} catch (SQLException sqlException){
//Non si verifica mai
}
}
...
}
© 2008 WS (WebScience srl) – All rights reserved
Gestire le eccezioni
WS © | 36
• Solo per situazioni davvero eccezionali
• Consistenti con il livello di astrazione
• Non ignorarle mai
• Approccio standard
© 2008 WS (WebScience srl) – All rights reserved
La potenza delle variabili
WS © | 37
© 2008 WS (WebScience srl) – All rights reserved
Come e dove
WS © | 38
private int somma;
public void conta() {
somma = 10;
int totale;
int parziale;
boolean fatto;
...
// codice che usa parziale
...
// codice che usa totale
...
// codice che usa fatto
}
© 2008 WS (WebScience srl) – All rights reserved
Come e dove
WS © | 39
• Immutabile tutto quello che può esserlo
• Una variabile per uno singolo scopo
• Inizializzare le variabili d'istanza nel costruttore
• Dichiarare le variabili locali vicino al primo utilizzo
© 2008 WS (WebScience srl) – All rights reserved
Minimizzare lo scope
WS © | 40
private void conta() {
1 totale = 0;
2 parziale = 0;
3 fatto = false;
...
20 totale = parziale;
...
40 if (parziale <= totale) {
...
}
60 while (!fatto) {
...
}
}
© 2008 WS (WebScience srl) – All rights reserved
Minimizzare lo scope
WS © | 41
• Limitare lo span
• Ridurre il tempo di vita
• Partire dallo scope più restrittivo
• Raggruppare le istruzioni correlate
© 2008 WS (WebScience srl) – All rights reserved
Il potere del nome
WS © | 42
public class Dipendente {
private String fn;
private Date b_d;
private boolean stringParsed;
...
public void stampaDipendente() {
if (b_d != null && stringParsed) {
Printer.print(this);
}
}
...
}
© 2008 WS (WebScience srl) – All rights reserved
Il potere del nome
WS © | 43
• Naming convention
• Descrizione accurata e completa
• Lunghezza necessaria (media tra 10 e 16 caratteri)
• Nome relativo al problema non alla soluzione
© 2008 WS (WebScience srl) – All rights reserved
Usare i condizionali
WS © | 44
© 2008 WS (WebScience srl) – All rights reserved
Istruzioni if-then-else
WS © | 45
if (stato < 0)
;
else {
stato = leggiStato();
if (stato == 0)
System.out.println(“Stato %s”,”valido”);
else {
stato = calcolaStato();
if (stato != 1)
System.out.println(“Stato %s”,”errore”);
else
System.out.println(“Stato %s”,”non errore”);
System.out.println(“Stato %s”,”calcolato”);
}
}
© 2008 WS (WebScience srl) – All rights reserved
Istruzioni if-then-else
WS © | 46
• Il percorso nominale è il primo
• Nessun ramo vuoto
• Verificare la necessità dell'else
• Annidamento massimo di 3 livelli
• Parentesi, sempre
© 2008 WS (WebScience srl) – All rights reserved
Catene if-elseif e istruzioni case
WS © | 47
if (input.equals(“#”) || input.equals(“@”) || input.equals(“=”)) {
tipo = SPECIALE;
} else if (input.equals(“,”) || input.equals(“;”) || input.equals(“.”)) {
tipo = PUNTEGGIATURA;
} else if (input.equals(“+”) || input.equals(“-”) || input.equals(“*”) || input.equals(“/”)) {
tipo = OPERATORE;
} else if ((input.compareTo(“a”)>0 && input.compareTo(“z”)<0) || (input.compareTo(“A”)>0 && input.compareTo(“Z”)<0) {
tipo = LETTERA;
}
© 2008 WS (WebScience srl) – All rights reserved
Catene if-elseif e istruzioni case
WS © | 48
• Casi ordinati per frequenza
• Azioni semplici per ogni caso
• Guard condition e funzioni booleane
© 2008 WS (WebScience srl) – All rights reserved
Controllare i loop
WS © | 49
© 2008 WS (WebScience srl) – All rights reserved
Scegliere quale loop
WS © | 50
• Numero cicli non noto → while
• Numero cicli noto → for
• Iterazione su collezioni → each/foreach
© 2008 WS (WebScience srl) – All rights reserved
Entrare ed uscire da un loop
WS © | 51
int i = 0;
int stato = -1;
...
// codice che usa i
...
for (i = 0; i < 100; i++) {
...
if (stato >= 0) {
i = 100;
}
...
}
stato = i;
© 2008 WS (WebScience srl) – All rights reserved
Entrare in un loop
WS © | 52
• Il punto di ingresso è unico
• Inizializzazione prima del loop
• Parentesi, sempre
© 2008 WS (WebScience srl) – All rights reserved
All'interno di un loop
WS © | 53
• Un loop svolge un singolo compito
• Aggiornare i contatori in un punto solo
• Non usare loop vuoti
• Annidamento massimo di 3 livelli
© 2008 WS (WebScience srl) – All rights reserved
Uscire da un loop
WS © | 54
• Deve terminare
• Non forzare l'uscita modificando il contatore
• Non utilizzare il contatore per altri scopi
• break e continue ma con cautela
© 2008 WS (WebScience srl) – All rights reserved
Ottimizzare con giudizio
WS © | 55
© 2008 WS (WebScience srl) – All rights reserved
Ottimizzare con giudizio
WS © | 56
“We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil.” ~ Donald E. Knuth
“We follow two rules in the matter of optimization: Rule 1. Don't do it. Rule 2 (for experts only). Don't do it yet - that is, not until you
have a perfecly clear and unoptimized solution.” ~ M.A. Jackson
© 2008 WS (WebScience srl) – All rights reserved
Ottimizzare con giudizio
WS © | 57
• Scrivere codice di qualità piuttosto che codice veloce
• Ottimizzare solo dopo aver riscontrato problemi di performance
• Misurare prima e dopo ogni passo di ottimizzazione
© 2008 WS (WebScience srl) – All rights reserved
Domande
WS © | 58
© 2008 WS (WebScience srl) – All rights reserved
Riferimenti
WS © | 59
• Code Complete 2nd EditionSteve McConnell
• RefactoringMartin Fowler
• Effective Java 2nd EditionJoshua Bloch
• http://wiki.webscience.it
© 2008 WS (WebScience srl) – All rights reserved
Valutazione
WS © | 60