Actual WORKING Production Code 4

Giuro che questo è attualmente in uso e serve decine di migliaia di utenti al giorno. Il frammento di codice è completo, non sono state rimosse linee nel mezzo.

while(e.hasMoreElements())
{
String pippo = (String)e.nextElement();
//log.debug(“\n\n\tHEADERS VALUE PRE: ” + pippo +
//”=” + request.getHeader(pippo));
}

Notare la linea commentata che rende la variabile pippo ancora più fondamentale per la corretta esecuzione del programma e in generale da senso a tutta la while.

Comments

Non posso credere che questo codice sia davvero usato!!!! :-D eheheheh Comunque complimenti per la solerzia con cui fornisci perle di saggezza agli utenti di questo blog!!!
Posted by Marco on 04/26/2006 06:25:24 PM

Che posso dire, ho la vocazione del grande educatore ;)
Posted by ratta on 04/26/2006 07:33:28 PM

Un’appendice di Effective Java, online

Per ora ho letto solo alcuni degli articoli di javatechniques.com . Ma per adesso ho davvero la sensazione che avevo avuto leggendo gli items del libro di Bloch. Roba che sapresti implementare/descrivere se ti capitasse. Che sai, ma che non enunceresti al volo, e che quindi è così spettacoloso leggere e averla pronta lì, bella ordinata e autorevole.

Comments

Url?
Posted by Matteo V. on 04/21/2006 04:56:52 PM

http://javatechniques.com Io ho letto “Compressing data sent over a socket” e “Faster deep copies of java objects”. Una nota : al contrario di Effective Java, il maggiore valore aggiunto che ho trovato sta nello studio del codice proposto (soprattutto per l’ottimizzazione) più che nei commenti, che servono solo a introdurre il sorgente.
Posted by ratta on 04/25/2006 09:15:28 AM

Quadrato estende rettangolo?

Un vero classico, a cui ho sentito/letto/visto rispondere molte volte.

Alla Java Conference 2005 ricordo che si è sfruttata questa domanda per dimostrare che ereditare in modo selvaggio può infrangere il principio di sostituzione di Liskov. In particolare questa era stata la dimostrazione (con buona approssimazione, sto andando a memoria) :

public class Rectangle {
private int base = 0;
private int height = 0;
…..
public void setBase(int base){
this.base = base;
}

public void setHeight(int height){
this.height = height;
}

public int getArea(){
return base * height;
}
}

public class Square extends Rectangle {

public void setBase(int base){
super.setBase(base);
super.setHeight(base);
}

public void setHeight(int height){
this.setBase(height);
}

}

public void testAreaIsTheProduceOfBaseAndHeight(){
Rectangle rectangle = new Rectangle();
rectangle.setBase(10);
rectangle.setHeight(5);
assertEquals(50, rectangle.getArea());
}

Visto che Square eredita da Rectangle possiamo in teoria sostituire un quadrato nella variabile rectangle :

public void testAreaIsTheProduceOfBaseAndHeight(){
Rectangle rectangle = new Square();
rectangle.setBase(10);
rectangle.setHeight(5);
assertEquals(50,rectangle.getArea());
}

Ovviamente questo test fallisce. Si potrebbe opinare che il test presume troppo rispetto all’implementazione di getArea, o rispetto all’implementazione dei due setters, o anche che il test dovrebbe tenere conto dell’oggetto concreto e non dell’astrazione. A questo rispondo che dentro al sistema comunemente non si conosce l’implementazione concreta, solo l’astrazione usata dalla variabile. Se non fosse così non staremmo programmando sull’interfaccia e tanti saluti polimorfismo. La triste verità è che visto che Square ha la stessa interfaccia di Rectangle abbiamo a disposizione un setter di troppo, con dei nomi che non fanno di certo pensare a un quadrato.
L’alchimia usata in Square negli override dei due setter (di per sè già brutta) mantiene le proprietà del quadrato, ma presenta comunque un’interfaccia che confonde il cliente dell’oggetto. Facciamo fare cose strane a dei setters per avere la coerenza, ma non abbiamo comunque un’interfaccia parlante.
Oltrettutto si infrange Dry (Don’t repeat yourself), perchè inseriamo la stessa informazione in due posti diversi.

La soluzione era definire un’astrazione comune a Square e Rectangle che definisca una getArea astratta e nessun setter (che in generale sono una pessima idea in un’astrazione che non presuppone una precisa struttura dati):

public abstract class Shape {
public abstract int getArea();
}

Poi, qualche tempo fa, mi sono ritrovato anche io a rispondere al classico.

La mia risposta ha seguito il manuale e sono finito sullo Strategy, che alla questione dell’area risponde bene. Ma in verità sono stato precipitoso.

A questo quesito, la prima risposta che io penso si dovrebbe proporre è un’altra domanda.
Quali caratteristiche di Quadrato e Rettangolo dobbiamo modellare?

Il motivo per cui spesso si pensa subito a Square extends Rectangle è che si pensa che la definizione matematica di queste due forme ne rappresenti la natura stessa e che quindi per descriverle correttamente si debba seguirla.

Ora, le relazioni matematiche tra le componenti delle forme geometriche, per quanto sia il metodo che viene usato per definirle a scuola, sono semplicemente la descrizione di uno dei tanti aspetti e interconnessioni di queste forme.

Pensare che gli oggetti debbano rappresentare la “natura” di un’entità, la sua identità, porta inesorabilmente a caricare la classe di responsabilità e quindi a rendere impossibile uno schema di astrazioni valido (dove per valido intendo sostituibile). E’ anche per questo che descrivere “extends” con “is a” è così pericoloso, sembra implicare che si parli della natura delle cose, mentre quello che gli oggetti rappresentano meglio sono i comportamenti delle cose. Altrimenti non si nasconderebbero le informazioni per pubblicarne i comportamenti, si nasconderebbero invece i comportamenti per pubblicarne le informazioni.

Però, se adesso qualcuno mi ponesse la domanda, e, alla mia seguente domanda, mi rispondesse che la caratteristica da rappresentare sono proprio le relazioni matematiche tra le componenti delle due forme, forse prenderei in considerazione di dire che “Square is a Rectangle”, ma a quel punto l’interfaccia di Rectangle non avrebbe nulla a chè vedere col calcolo dell’area e i dati immagazzinati non sarebbero certamente base ed altezza.

Actual WORKING Production Code 3

Era un po’ che non trovavo una vera chicca, sfortunatamente il codice ora è abbastanza a posto e non offre linee da record. Una patch arrivata qualche giorno fa però conteneva una vera sorpresa pasquale :

boolean passAttribute = (“y”.equalsIgnoreCase(itemBean.getPassAttribute())) ? true : false;

40 linee più sotto (pare che quest’anno in California vadano di moda i metodi lunghi) troviamo l’unico uso di questo eccezionale booleano :

if(passAttribute){
Una sola, banale, linea
}

Io trovo l’insieme di una bellezza e forza sconcertanti. Beh, forse bello e forte non è, ma sconcertante di sicuro.