Actual WORKING Production Code 6

Era molto che non avevo modo di proporre pezzi di codice veramente di valore. Ma il fato per oggi aveva qualcosa di spettacolare in serbo per me : ho tempo fino a questa sera per capire che cosa fa una certa classe (e le sue vicine) e capire se l’algoritmo contenuto in essa si adatta a un’altra piattaforma.

Ecco uno dei punti di più alta scuola contenuti in questa classe :

i++;
if(abyte0[i] == 45 && abyte0[i + 1] == 45)
{
do
{
for(i += 2; abyte0[i] != 45; i++)
if(abyte0[i] == 100 && abyte0[i + 1] == 111 && abyte0[i + 2] == 99 && abyte0[i + 3] == 105 && abyte0[i + 4] == 110 && abyte0[i + 5] == 102 && abyte0[i + 6] == 111 && abyte0[i + 7] == 58 && abyte0[i + 8] == 99 && abyte0[i + 9] == 104 && abyte0[i + 10] == 117 && abyte0[i + 11] == 110 && abyte0[i + 12] == 107 && abyte0[i + 13] == 45 && abyte0[i + 14] == 104 && abyte0[i + 15] == 101 && abyte0[i + 16] == 114 && abyte0[i + 17] == 101)
return true;

i++;
} while(abyte0[i] != 45 || abyte0[i + 1] != 62);
i += 2;
} else
if(abyte0[i] == 91 && abyte0[i + 1] == 67 && abyte0[i + 2] == 68 && abyte0[i + 3] == 65 && abyte0[i + 4] == 84 && abyte0[i + 5] == 65 && abyte0[i + 6] == 91)
{
for(i += 7; abyte0[i++] != 93 || abyte0[i] != 93 || abyte0[i + 1] != 62;);
i += 2;
}

Magic number for President!

Invidiosi eh? Tutti vorrebbero fare il mio lavoro oggi. E’ come andare alla fiera mondiale del masochismo, con il mal di denti.

Comments

Questa dovresti mandarla al Daily WTF…
Posted by Paolo Perrotta on 02/23/2007 08:42:01 PM

porco mondo! Hai proprio tutte le fortune tu… ;-))
Posted by domenico on 03/08/2007 10:16:07 AM

Se passate da Torino il 21 febbraio

Si parlerà di un pattern da me molto amato, Decorator. E’ un peccato che Decorator porti a dei problemi di identità. Davvero!

Intanto questo è link con i dettagli sul meeting :
http://www.jugtorino.it/vqwiki/jsp/Wiki?MeetingFebbraio2007

Se non conoscete Decorator è meglio aspettare di leggere quanto segue fino a chè non avrete seguito il meeting di cui sopra.

Ora… perchè Decorator porta a problemi di personalità?

Supponiamo di avere una lista di oggetti di tipo User :

List registeredUsers = new ArrayList();

Abbiamo poi un metodo :

public void register(User user) {
if(!registeredUsers.contains(user)) registeredUsers.add(user);
}

Nulla di particolare no? Se non per il fatto che si potrebbe evitare di usare una ArrayList e passare all’uso dei Set, ad esempio di TreeSet, per assicurarsi automaticamente dell’unicità dello user. Ma questo renderebbe meno chiaro il problema, visto che nasconderebbe parte della logica.

Passiamo al nostro Decorator ora :
User è un’interfaccia, che viene implementata da SystemUser e da tre Decorators : AdminUser, TemporaryUser e RemoteUser. Ognuno di questi Decorators, una volta wrappato attorno a uno User…

classico : user = new AdminUser(user);

…aggiunge alcune funzionalità al SystemUser in modo del tutto trasparente e dinamico. Bello il decorator eh?

Ma il decorator è davvero così trasparente? Lo è e non lo è. Per le operazioni di uguaglianza non lo è per niente : il metodo di cui sopra, che controlla se un utente è già registrato prima di registrarlo, verrà sviato dal fal fatto che lo user che gli stiamo passando, per quanto sia solo un guscio attorno a un altro user, avrà un identità, nello heap degli oggetti, del tutto diversa dall’oggetto che contiene.

Per quello che deve fare il nostro manager di registrazione degli utenti, a noi piacerebbe tanto che :

registrator.register(user);
registrator.register(new AdminUser(user));
assertEquals(1,registrator.size());

E in vece no… ci ritroveremo due utenti registrati, quando di fatto si tratta dello stesso utente registrato due volte, sotto forma di due oggetti diversi, per quanto intimamente legati.

In breve, Decorator non è per niente trasparente all’operatore di identità. Allo stesso modo un oggetto che ne decori un altro dovrebbe assicurarsi di fare l’override sia di hashCode() che di equals() in modo da invocare il decorato anche in quel caso, come per i metodi dichiarati in User.

Peccato che “==” non sia a sua volta un metodo di cui poter fare l’override.

Risolvere questi problemi di identità pur continuando a usare Decorator spesso necessita di discriminare tra una classe e l’altra. Per evitare degli instanceof (brrr!!) viene in soccorso Visitor… ma non è la stessa cosa, parte dell’eleganza e compattezza data Decorator viene annullata dall’uso di Visitor che, per quanto sia un gran pattern, è tanto furbo quanto è poco elegante/chiaro.

Se te lo dicessi poi dovrei ucciderti

Lavoravo per la Spectre e non lo sapevo…

Riassumo qui (senza distorcere alcuna affermazione, spesso si tratta di testuali parole) un geniale scambio di mail di cui sono stato testimone diretto e in parte attore.

Joe : aumentate il livello di logging sulla preproduzione

Bill : ok, ma voi loggate troppo

Joe : ci serve, è una piattaforma di test e analisi, no?

Bill : già, però andate contro allo standard

Joe : quale standard?

Bill : il nostro

Joe : posso vederlo?

Bill : no

Joe : puoi dirmi che cosa fare per rispettarlo?

Bill : si, ma potrei finire nei guai, quindi no

Joe : come faccio a rispettare uno standard segreto?!

Bill : quando lo starai rispettando io non ti dirò più che non lo stai rispettando

Joe : scherzi?!

Bill : no, ma per il tuo bene dimentica quello che ti ho detto

Giuro che questa è una riproduzione fedele dello scambio, l’originale aveva affermazioni ancora più assurde e spy-like. Ma se le divulgassi potrebbero uccidermi! Si tratta di logging in fin dei conti, non finisce mica a tarallucci e vino!

Comments

Bill ti stava prendendo per i fondelli…
Posted by Matteo on 02/06/2007 01:32:18 PM

Magari! E invece no. Se no stava prendendo per i fondelli molta gente (io ero solo in copia durante la maggior parte dello scambio)
Posted by ratta on 02/06/2007 01:52:22 PM

Non posso che confermare che quanto riportato è praticamente fedele alla realtà!!! E’ un mondo difficile … Ottima scelta il nome Bill!!! (Dietrologia spicciola)
Posted by trogloditaIT on 02/09/2007 03:52:49 PM