giugno 2005 Blog Posts

Un'altra tecnica molto comoda quando si parla di "defensive programming" è la cosiddetta "programmazione funzionale".

Vediamo lo stesso programma di prima, però adattato a questa nuova tecnica.

Program Programma;

const ErrEmptyStrValue = 1;

function ReadString(Label : String;var S : String;var ErrOut: Integer) : Boolean;
begin
  write(Label+': ');
  readln(S);
  Result := S <> '';
  if Not Result then
    ErrOut := ErrEmptyStrValue;
end;

function GetFirstName(var S: String;var ErrOut : Integer);
begin
  Result := ReadString('First name',S,ErrOut);
end;

procedure GetLastName(var S : String;var ErrOut: Integer);
begin
  Result := ReadString('Last name',S,ErrOut);
end;

var FName,LName : String;
     ErrorOut : Integer;

begin
  if GetFirstName(FName,ErrorOut) then
  begin
     if GetLastName(LName,ErrorOut) then
     begin
        write('First name is '''+FName+' '' and Last name is '''+LName+'''');
     end;
  end;
end.  

Qui adesso abbiamo un programma che controlla che ogni funzione sia "true" prima di proseguire.
Inoltre, dotando le funzioni di un parametro ErrOut, possiamo usare un tipo Boolean e relegare la
gestione dell'errore in altri punti. Nel caso specifico, non gestiamo l'errore nel corpo principale
soltanto perché si tratta di un programma dimostrativo e perché ad ogni modo in un programma di
questa complessità usare la programmazione funzionale è - imho - fuori luogo, oltre che
tremendamente noioso .

Comunque il concetto di base è semplice: valori TRUE o FALSE a seconda dei casi, più una
variabile di supporto per la gestione corretta degli errori in altri punti. Oggi useremmo probabilmente una
eccezione per cose del genere, ma il concetto non cambia poi molto.

Il vantaggio principale di questo stile di programmazione è che sai *sempre* dove stai se qualcosa non và, il che non fà male di sicuro .

Saluti,

Andrea

powered by IMHO 1.2

Si parla tanto, tantissimo di dotNET e di come sia una gran bella tecnologia. Bene, penso sia arrivato il momento di guardarla anche da altri punti di vista. Il mio è quello di uno che, di base, è abbastanza informato anche se non si è ancora addentrato in tutti i meandri di dotNET. Spero non ci siano informazioni sbagliate, quindi dico quello che so sperando che sia giusto .

Cominciamo dal fatto che dotNET esiste anche per altre piattaforme, più precisamente Mono, che è standard e tutte 'ste robe qui.

Non so se qualcuno ci ha fatto caso, ma MS cerca a tutti i costi di uscire con dotNET2 mentre i ragazzi di Mono stanno ancora cercando di arrivare a finire la corrispondenza alla 1.1 di dotNET. Questo la dice lunga su quanto sia "completo" il port e quanto MS sia disponibile a che dotNET sia multipiattaforma. Qualcuno potrebbe quindi chiedersi il perché della decisione di Microsoft di standardizzare C# ed il CLR.
La mia opinione è che sia stata una mossa geniale, oltre che un grandioso specchietto per le allodole: una standardizzazione non significa necessariamente dover seguire lo standard e Microsoft ha dimostrato più volte di essere allergica agli standard, perfino i suoi medesimi(vedi pasticcio con le typelibraries di Office, tanto per citare l'esempio più conosciuto, oppure perfino le incompatibilità di dotNET 1.1 SP1). Inoltre, Visual Studio ha la fetta più grossa di mercato su dotNET, questo è indubbio, quindi la stragrande maggioranza di coloro che vorranno usare dotNET lo faranno con VS.
Perché il designer WinForms è stato incluso nel framework? Semplice, perché non è su quello che si basano i proventi di Visual Studio, ma sulla vendita del prodotto in se e sui servizi accessori. Ancora una volta, un modo per Microsoft di attrarre persone e dare una parvenza di non monopolio(rendendo ad esempio possibile la realizzazione di SharpDevelop). Dunque, qui mi pare adesso sia chiaro, no?

Passiamo ad un altro punto fondamentale: Microsoft dice che dotNET risolverà il problema dell'inferno delle DLL(altrimenti noto come DLL Hell). In cosa consiste questo ecc. Il risultato era un malfunzionamento generalizzato delle applicazioni coinvolte.problema? Nel fatto che un certo(alto, molto alto) numero di sviluppatori non ha fatto "le cose perbene"(cit) e quindi alcune DLL andavano a sovrascriverne altre, senza alcuna accortezza per i numeri di versione, generando malfunzionamenti di ogni sorta e specie.
Dunque, lo strumento "principe" per la risoluzione di questo problema in dotNET è l'uso dello strong naming. Come funziona? Semplicemente, si "firma" un assembly con un certificato che attesta che l'assembly ha la versione X.Y e che quindi tutte le applicazioni che fanno riferimento a quella versione di quell'assembly sanno che è lui. Parte fondamentale di questo processo è la Global Assembly Cache, GAC per gli amici, che appunto conserva gli assembly più utilizzati. Cosa succede, però? Nonostante sia possibile registrare degli assembly nella GAC, Microsoft sconsiglia questa pratica a quanto ho capito.
Ergo, strong naming ti saluto. Inoltre, so che non ce n'è bisogno ma lo dico lo stesso, è normale che se non vengono rispettate le regole di base di "civile convivenza" tra gli assembly e compagnia, qualcosa di molto, molto, molto brutto dovrà succedere prima o poi, vi pare?

Adesso invece, occupiamoci della "portabilità": qui il discorso deve prendere una ramificazione dicotomica. Il problema è che bisogna distinugere tra lato server e lato client. Non solo, ma anche tra diverse versioni del Framework, perché ormai ci avviamo alla 2.0 ed il numero sta crescendo in modo preoccupante. Il perché di questa mia preoccupazione lo vediamo dopo. Occupiamoci intanto del fattore portabilità sul lato client. Voi mettereste il motore di una macchina moderna dentro ad una vecchia 500? Non penso proprio. Però è, in poche parole, quello che vorrebbero fare con dotNET ed i varii Windows(9x,ME, ecc). Capite bene che non solo mi sembra un'idea abbastanza peregrina di concetto(ed infatti nessuno osa ammetterlo pubblicamente), ma anche, a mio parere, praticamente irrealizzabile, vista la frequenza dei crash di Windows 98, tanto per dirne uno. Non mi si venga per favore a dire che non ce ne sono più, perché non è semplicemente vero. Una mia cara amica ha Windows ME. Un altro amico ha 98. Ce ne sono molti di più di quanti molti di noi spererebbero, mi sa, e non soltanto in ambito aziendale.

Ho voluto affrontare il tema della portabilità in maniera dicotomica perché la questione della "compatibilità" delle varie versioni del framework tra loro è un fattore importante. Molto importante. Stando a questo articolo, le cose non sono rosee per dotNET2, per i motivi riportati. "Certo, comunque in caso di problemi si può sempre usare il framework 1.1 side-by-side", viene detto. Sicuro, aggiungo io, tanto non abbiamo mica altri programmi da far girare sul sistema no - oltre alle applicazioni dotNET. Facendo un rapido conto e mantenendosi su una media di 20MB a framework e considerando il caso peggiore(1.0, 1.1 SP1 e 2.0), soltanto di base ci portiamo dietro la bellezza di 60 MB. Naturalmente, non è finita qui, perché oltre al CLR dobbiamo anche portarci i vari assembly che, vale la pena ricordarlo, sono DLL. Già, sono DLL, però non condividono lo spazio di memoria. Quindi per ogni applicazione avremo un caricamento di tutte le DLL. Tanti auguri.

Altro da aggiungere? Direi di si... spesso si dice che esiste NGEN, un tool capace di preconvertire il codice IL in codice nativo... già... ne vogliamo parlare? Questo articolo, fà chiaramente intendere come stanno veramente le cose, al di là della propaganda e non sono cose da poco. Il perché è presto detto: nell'articolo si dice(testualmente):" The downside, of course, is that whenever the runtime (for example via a Service Pack) or one of the dependencies of your ngen images changes (version upgrade or patch), your ngen image becomes invalid". Capito? Quindi, non solo valgono soltanto per il computer per il quale vengono generate, ma anche soltanto fino al prossimo update di una qualsiasi cosa che in qualche modo modifichi lo stato del sistema inerentemente all'immagine considerata. Credo che sia abbastanza ovvio che sia così, perché è chiaro che se cambia qualcosa magari cambiano gli indirizzi e così via, però fà anche capire che il trade-off nella maggior parte dei casi, almeno dal mio punto di vista, non è accettabile.

Bene, per ora mi fermo qui, anche se avrei molte altre cose da dire... però prima preferisco aspettare i commenti .

Buona Domenica,

Andrea

powered by IMHO 1.2

posted @ domenica 5 giugno 2005 20:23 | Feedback (612) | Filed Under [ Altro ]

Ottimo, pare che finalmente non dovrò più smadonnare .

Questo è soltanto "buono", come dire... grassie Boschin!

Qualcuno può dirmi in che linguaggio è scritto IMHO? Non fatemi scaricare i sorgenti, su...

Buona giornata

powered by IMHO 1.2

posted @ sabato 4 giugno 2005 14:53 | Feedback (502) | Filed Under [ Altro ]
Cos'è la programmazione difensiva?

E' una tecnica che rende i programmi più facili da scrivere e mantenere.
Tanto per fare un esempio, uno stupidissimo programma in Pascal.

Program Programma;
procedure ReadString(Label : String;var S : String);
begin
write(Label+': ');
readln(S);
end;

procedure GetFirstName(var S: String);
begin
ReadString('First name',S);
end;

procedure GetLastName(var S : String);
begin
ReadString('Last name',S);
end;

var FName,LName : String;
begin
GetFirstName(FName);
GetLastName(LName);
write('First name is '''+FName+' '' and Last name is '''+LName+'''');
end.

Ecco, questo programma illustra bene quello che intendo.
Anzitutto, c'è una procedura(per i ragazzi abituati al C: una void function) che prende due parametri: una etichetta di tipo stringa che rappresenta il messaggio da visualizzare ed una variabile S che conterrà il dato letto. Il nome dice bene cosa fà: legge una stringa. Non ci si può sbagliare. I parametri indicano bene a cosa servono. Impossibile sbagliarsi.
Ce ne sono altre due che si appoggiano ad essa e diminuiscono il numero dei parametri: da due si passa ad uno, mentre l'altro viene riempito al volo. Semplice e molto, molto, molto chiaro.

Infine ci sono le due variabili: mentre si vanno ad utilizzare è difficilissimo sbagliarsi e mettere LName al posto di FName, perché basta rifarsi ai nomi dei metodi.

Queste sono le "basi" della programmazione difensiva... ma se vorrete, si può anche vedere dell'altro...
Ciao,

Andrea
Sto valutando oggi(e nei prossimi giorni) una serie di OPF.
Cosa è un OPF e a cosa serve?

E' uno strumento in grado di mappare le classi business sul database senza dover scrivere query, codice di collegamento, e tutte queste cose qui che sono sinceramente abbastanza noiose. concentrandosi sulle caratteristiche dell'applicazione.

Serve dunque a semplificare lo sviluppo... ma siamo sicuri?
Il problema principale di questo genere di strumenti, infatti, è proprio questo: la quantità di codice da scrivere, in molti casi si sposta da quanto detto prima ad altri ambiti, come la mappatura delle classi ad esempio.

Voi li usate gli OPF?

Se si, quali?

Aggiornamento: pare che non ci siamo capiti :-)

Il 99% del mio lavoro si svolge ancora su Win32.
Scorribbando in dotNET soprattutto perché so che prima o poi mi capiterà di lavorarci seriamente ed ovviamente non voglio arrivare poi a dover imparare tutto magari in poco tempo facendo macelli.

Secondariamente, uso principalmente VCL.NET nei miei progetti dotnetizzati :-)

Altra cosa: per quei(pochi?) di voi interessati, presto dovrei avere un articolo su Delphi da pubblicare qui su UGI.

Saluti,

Andrea
P.S. Che odio quella dannata verifica numerica.
P.P.S: che odio dover mettere i tags HTML :-P
Quanti di voi non mi conoscono, mi chiamo Andrea, classe 1977, Napoletano. Sono principalmente un programmatore Delphi, ma non disdegno incursioni selvagge nel mondo dotNET, sia con Delphi che con C#. Bene, adesso che ci conosciamo un pò meglio, comincerò a postare di programmazione. Se vi state chiedendo il significato di "Pensieri malcelati"... beh, il fatto è che non sempre esprimo giudizi positivi, e quando questo accade i pensieri sono, per l'appunto, malcelati :-) Buon divertimento con i miei post, sia che siate d'accordo, sia che non lo siate :-) Andrea
posted @ venerdì 3 giugno 2005 19:14 | Feedback (114) | Filed Under [ Altro ]