Delphi - văzut de aproape

După schimbările ce au survenit în orientarea firmei Borland, cel mai nou produs al acesteia, Delphi, a fost asteptat cu mult interes. Asăzi Delphi există. Cum este văzut însă de proiectanti?

Alin Flaidăr

Trei ani de la aparitia ultimei versiuni de Turbo Pascal au fost, categoric, prea mult. Doar fidelii Pascal-ului au mai rezistat tentatiei Visual Basic sau ofertei C++. Pentru a-si recâstiga adeptii, Borland face o miscare spectaculoasă si riscantă. Noul stil de dezvoltare a aplicatiilor propus de Delphi lasă să se întrevadă o perspectivă terifiantă si foarte probabilă a viitorului programării: vom pluti printre sute de obiecte din care ne vom alege vizual cărămizile constituente ale aplicatiei. Utilizatorii vor redeveni - ca la începuturi - dezvoltatori, iar programatorii veritabili vor scrie biblioteci de obiecte integrate în sistemul de operare.

Putină istorie

Până la impunerea Windows 3.0, Turbo Pascal devenise un standard de facto al dezvoltării facile de programe pentru DOS. Viteza mare de compilare-linkeditare, biblioteca de sistem bogată în functii, limbajul simplu si cu verificare strictă a tipurilor făceau din el o sculă foarte productivă la nivelul cerintelor de atunci. Schimbările bruste de tehnologie care au zguduit lumea simplă single-task si în mod real de adresare a DOS-ului au prins pe picior gresit dezvoltatorii Turbo Pascal-ului. Încercările de a promova o interfată obiectuală pentru DOS (Turbo Vision) si suportul limitat oferit pentru DOS -mod protejat (un DPMI pe 16 biti) au demonstrat că Borland a ales gresit calea de dezvoltare a compilatorului.

Versiunea Windows nu era consecventă cu modul facil de programare practicat de majoritatea utilizatorilor de Turbo Pascal. Obligativitatea utilizării de pointeri, type-casting si definirii de noi obiecte pentru orice functie specifică au speriat programatorii care erau foarte fericiti până atunci utilizând numai variabile statice si locale. Object Windows nu scutea suficient programatorul de contactul cu interfata urâtă si încâlcită Windows API, iar interactiunea directă cu mesajele Windows nu elimina necesitatea scrierii de cod care să compenseze neajunsurile si să ocolească fundăturile Windows. În ciuda unei remarcabile implementări a lui Object Pascal, Borland continua să furnizeze biblioteci obiectuale numai pentru construirea de interfete si prea putin pentru manipularea structurilor de memorie si a bazelor de date, în timp ce devenise evident că realizarea interfetelor cu utilizatorul era o treabă de design vizual. Urmarea a fost că programatorii nepretentiosi au migrat spre Visual Basic în timp ce profesionistii au optat pentru C++, de la care Pascal împrumutase deja prea mult.

Venise timpul pentru o cotitură în strategia firmei si, după debarcarea lui Philippe Kahn, noul mediu de dezvoltare Pascal al firmei a fost substantial restructurat, dotat cu o remarcabilă bibliotecă de obiecte si orientat spre realizarea rapidă de aplicatii.

De ce RAD?

Borland a învătat bine lectia lui Visual Basic care a arătat clar ce asteaptă dezvoltatorii în materie de producere rapidă a unei aplicatii (si nu care este directia de evolutie a limbajelor de programare).

Dacă la începuturile programării Windows raportul între durata de realizare a interfetei cu utilizatorul si cea de implementare a functionalitătii propriu-zise a aplicatiei era de 20:1, biblioteci precum OWL, MFC sau Zinc au redus raportul la 3:1, acum dezvoltatorul modern pretinde să nu petreacă mai mult de 5-10% din timp desenând interfete. Migrarea aplicatiilor de baze de date spre Windows si arhitecturi client-server au impus aparitia extensiilor de baze de date în mediul de dezvoltare vizuală. În mod logic, au urmat obiectele cele mai frecvent utilizate astfel încât mediile RAD curente sunt destul de complexe si heterogene, excelând într-un aspect sau altul dar nesatisfăcând nici unul toate dezideratele: compilator generator de cod executabil real, arhitectură deschisă, limbaj obiectual complet, flexibilitate a relatiei cod - obiecte vizuale. Sisteme precum Visual Basic si Power Builder schioapătă la capitolul limbaj în timp ce expertii din Borland C++ si vrăjitorii lui Visual C++ sunt exemple de cum nu trebuie să functioneze un mediu de dezvoltare vizuală.

Un compilator exceptional de rapid si un limbaj obiectual evoluat si revăzut capabil să creeze executabile independente si module DLL au creat premizele devenirii RAD a mediului Turbo Pascal. Conceperea unui mediu vizual de dezvoltare deosebit de puternic si elastic bazat pe componente vizuale ca obiecte reutilizabile, dezvoltarea unei biblioteci de aproape o sută de componente de bază, introducerea de componente cu suport de baze de date locale si partajate în retea ca si de arhitecturi client-server au completat ceea ce în final s-a chemat Delphi.

Sintagma RAD este cât se poate de reală: doar câteva minute pentru producerea unei forme de editare date în cod executabil self-consistent.

Turbo Pascalul renaste din cenusă si are toate sansele să-si recâstige adeptii iar Borland Intl. actionarii.

Meet Delphi!

Primul contact cu Delphi a fost - indiscutabil - deconcertant. Un toolbar, un spatiu de desen, mi-au trebuit cinci minute să descopăr editorul de cod si jumătate de oră să localizez programul principal - acum botezat Delphi project.

Părea de neconceput să începi un program desenând, asa încât m-am grăbit să mă asigur că Delphi compilează mai vechile aplicatii Borland Pascal 7.0. Nu a fost prea simplu, dar după ce am modificat referintele la unitatea Win31 din clauzele uses si am rebotezat o variabilă ce se numea Result - acum nume rezervat pentru rezultatul returnat de o functie, Delphi a compilat fără probleme în 3 secunde cele 11.000 de linii ce alcătuiau o aplicatie de anvergură medie. Codul rezultat părea ceva mai mare decât cel generat de BP 7 dar a revenit la normal după ce am eliminat optiunea Pentium safe FDIV care determina link-editarea unei biblioteci proprii de virgulă mobilă. Aparent, Borland nu a îmbunătătit compilatorul său clasic de 16 biti decât sub aspectul vitezei de compilare. Am fost dezamăgit totusi că - nici cu Delphi - Object Pascal nu a evoluat spre cod pe 32 de biti, chiar dacă principalul concurent se numeste acum Visual Basic.

Cu fiecare versiune de compilator, Borland a propus o nouă solutie si a promis o crestere a productivitătii. La vremea lor Turbo Vision si Object Windows au fost revolutionare si au necesitat o revedere a conceptiilor despre programare si am sperat că Delphi nu va fi mai pretentios. Din nefericire autorii lui au vizat atragerea neinitiatilor si au făcut prea putin pentru readaptarea veteranilor. Mediul si chiar limbajul sunt o discontinuitate evidentă fată de produsele anterioare si promisiunea compatibilitătii nu este însotită si de cea a reutilizării codului mai vechi.

Obisnuit cu generatoare clasice de cod gen ProtoGen sau Application/Class expert din BC++ mă asteptam să întâlnesc ceva similar, cu o succesiune clasică dezvoltare vizuală - generare cod - modificare si scriere de cod specific, axată pe derivarea de noi clase pentru fiecare functie specifică.

Obiecte vizuale

În Delphi însă, editorul vizual este strâns integrat cu editorul de cod. Acestea sunt permanent sincronizate si, chiar dacă relatia nu este în ambele sensuri, conceptul este cel de lucru alternativ în ambele planuri, cu accent pe editorul vizual care pilotează scrierea procedurilor de cod specific ca rutine de tratare a evenimentelor.

Entitătile cu care operează editorul vizual corespund la obiecte de tip component în codul Pascal. Numai clase neabstracte derivate din tipul TComponent pot fi integrate în biblioteca de componente a editorului vizual.

Aplicatia este văzută ca un ansamblu de forme - ferestre si dialoguri clasice Windows - care ocupă un rol central în arhitectura programelor. Forma este entitatea care cuprinde celelalte componente si al cărei scop global permite o viziune completă a interactiunii acestora si facilitează obtinerea unei functionalităti specifice. Reflectarea formei în cod se face ca o unitate distinctă (Pascal unit) care declară în partea de interfată o clasă de tip TForm având drept câmpuri obiectele componente. Initial noua formă nu include metode specifice, dar contine o apreciabilă doză de functionalitate prin cele câteva zeci de metode private si publice mostenite de la TForm ca si prin comportamentul standard al obiectelor componente care asigură aspectul si controlul interactiunilor dintre componente. În faza aceasta forma este perfect compilabilă si utilizabilă chiar fără vreo linie suplimentară de cod. Cum din unitatea asociată de cod nu reiese nimic, este firesc să te întrebi cum sunt încorporate defintiile proprietătilor, pozitiilor componentelor si formei, într-un cuvânt, desenul? Răspunsul este dat de asocierea fisierului unitate cu un fisier de tip resursă binară Windows (cu extensie DFM) care se link-editează în codul executabil si are acelasi rol ca si resursele standard dar care nu contine dialoguri, imagini bitmap sau iconuri, ci un format special încărcat de constructor la crearea obiectului formă.

Componentele "vizibile" pot fi controale clasice Windows gen butoane, editoare, liste de selectie, etc. dar si o varietate de controale sofisticate cu functii noi oferite în standard de Delphi. Tot vizibile sunt si componentele de tip dialog care automatizează functiile comune de tip selectie de fisier, font, culoare, etc. În spatele interfetei cu utilizatorul de pe formă se găseste artileria grea - componentele invizibile care conferă functionalitate aplicatiei din care cele mai semnificative sunt obiectele de acces la bazele de date. Un avantaj remarcabil îl conferă lui Delphi capacitatea de a produce si integra în bibliotecă componente complet noi sau derivate din tipurile existente, ca si controale în format VBX 1.0.

Particularizarea unui component se face prin modificarea vizuală a proprietătilor acestuia. Inspectorul de proprietăti permite specificarea aspectului unei forme sau al unui control vizibil din formă facilitând spre exemplu setarea culorii, a unui font specific, etc. Mult mai spectaculoase sunt proprietătile care descriu interactiunea componentelor cu alte componente sau cu structuri de date în memorie sau pe disc, diferentierea comportamentului în interactiune cu utilizatorul. Toată această informatie se stochează în întregime în resursă si permite, spre exemplu, conceperea unei machete sofisticate de introducere a datelor fără generarea vreunei metode specifice în sectiunea de cod.

Celor cărora manipularea obiectelor prin proprietăti în faza de dezvoltare li se pare firească le reamintesc că nu au de-a face nici cu Basic, nici cu Paradox sau Fox, în care proprietătile se interpretează precum întregul cod de altfel, cu penalizările corespunzătoare de performantă si consum de resurse. Integrarea conceptului de proprietate într-un limbaj compilat prin excelentă este un pas remarcabil într-o lume în care modificarea functională a unui obiect nu era posibilă decât în timpul executiei (la runtime), prin apeluri de metode !

Obiectele crează evenimente

Exigentele de mediu de dezvoltare rapidă de aplicatii presupun mai mult însă decât asamblarea aplicatiei din cărămizi standard. Când si unde se scrie codul care determină functiile specifice ale aplicatiei?

Nimeni si nimic nu împiedică programatorul să scrie în cea mai clasică manieră unităti întregi de obiecte si functii Pascal, ce pot fi integrate firesc în proiectul Delphi. Mediul Delphi nu pilotează dezvoltatorul în programarea clasică algoritmică si nici nu dispune de un class expert care să faciliteze dezvoltarea de noi obiecte. Delphi gestionează utilizarea de obiecte.

Când un component întâlneste o conditie deosebită - spre exemplu, un clic de mouse pe un component-buton sau actualizarea unei înregistrări pe disc pentru un component-tabelă - acesta generează un eveniment care se traduce prin apelul unei metode dedicate a formei care contine obiectul, al cărei scop este executarea unei functii specifice. Evenimentele care pot fi generate de un component sunt accesibile în editorul vizual, la fel ca si proprietătile: un dublu clic pe un eveniment din listă si Delphi selectează sau generează automat o metodă specifică pentru formă si plasează cursorul în editorul de cod acolo unde trebuie scris sau există deja codul specific evenimentului.

Această tehnică de notificare a formei de către component la aparitia unui eveniment reprezintă o modalitate elegantă de delegare a responsabilitătii reactiei către formă, singurul obiect care detine o perspectivă globală si este în măsură să actioneze corespunzător.

Imaginati-vă cum era rezolvată până acum următoarea situatie în limbajele obiectuale cele mei evoluate: un clic pe un buton trebuie să determine inserarea unui text dintr-un editor într-o listă de selectie (listbox). Din clasa TButton trebuie derivată o nouă clasă având o metodă ButtonClick care reactionează la clic, în care se accesează prin typecasting pe câmpul Parent câmpurile editor si listă ale formei-părinte pentru efectuarea operatiunii. Pentru comparatie, în Delphi nu este necesară instantierea unei noi clase de buton si nici un typecasting complicat pentru că forma detine în scopul său accesul la toate componentele; ajunge legarea unei metode a formei de evenimentul butonului.

Practic, cu exceptia formelor pe care oricum le întretine Delphi, nu este necesară definirea de noi clase pentru realizarea unei aplicatii respectabile. Cosmarul creării de clase noi s-a topit. Portile sunt larg deschise fanilor Visual Basic-ului.

Ce s-a ales din Pascal?

Îmi amintesc recenzia primului Turbo Pascal for Windows din Dr. Dobbs, în finalul căreia Jeff Dunteman răpea orice sperantă eventualilor programatori care se vedeau rescriind Excel-ul într-un weekend. Ei bine, un Excel nu, dar un program de calcul tabelar, multi-document, cu suport OLE a devenit perfect fezabil în câteva zile si sute de kilobytes.

Care este însă pretul care a trebuit plătit pentru a obtine un mediu capabil de o asemenea performantă? Pare greu de imaginat, dar Borland a considerat că gâtuirea productivitătii se producea chiar în clasicul, bătrânul, productivul Pascal. Noutătile introduse în limbaj fac ca un bătrân pascalist care le supravietuieste să fie perfect adaptabil la viata subacvatică a omenirii din secolul 34. Pentru menajarea lui să precizăm din start că include încă sintaxa, cuvintele rezervate si functiile standard ale vechiului Pascal.

Evident, cele mai dramatice schimbări au fost operate chiar la nivelul obiectual. Noul tip de obiect, declarat acum folosind cuvântul rezervat class, nu poate exista decât ca pointer si instantiat dinamic în heap prin apelarea constructorului. Urmare a faptului că toate obiectele sunt acum pointeri, s-a eliminat necesitatea dereferentierii lor explicite prin simbolul ^. Noile obiecte sunt referite astfel NewObject.Field, echivalent cu vechiul model OldObject^.Field. O inovatie gratuită poate, mirosind a concesie pentru "vizual-băzicari".

A fost introdus strămosul comun implicit al tuturor claselor, TObject, care asigură polimorfismul obiectelor la cel mai jos nivel.

Câmpurile componente si metodele gestionate de editorul vizual sunt plasate în sectiunea implicită a obiectului formă, fiind obligatorie includerea explicită în sectiunile public si private a câmpurilor si metodelor declarate de programator.

Noi tipuri de sectiuni au apărut în declararea tipului de obiect. Protected permite accesul la câmpuri si metode declarate astfel numai obiectelor descendente, delimitând astfel interfata obiectului între utilizatori si dezvoltatori de obiecte.

O remarcabilă noutate este declaratia published care extinde accesul la câmpuri si metode ale unui obiect în afara modulului executabil, făcând astfel posibil exportul de interfete de obiecte către alte aplicatii. O initiativă similară din partea Microsoft ne-ar fi scutit de interfata inter-aplicatii stupidă si lacomă de resurse numită OLE! Cea mai evidentă utilitate a publicării obiectelor este posibilitatea editorului vizual de a avea acces la numele si tipurile proprietătilor exportate de obiectele componente rezidente în biblioteca dinamică de componente (un modul DLL numit complib.dcl). Modul de acces la obiecte publicate nu este specificat de Borland în documentatia standard care însoteste pachetul dar este de asteptat să fie disponibil în documentatia limbajului Object Pascal sau via Internet.

Care este secretul implementării proprietătilor obiectelor? Cum este posibil să scrii Editor.Visible := true si câmpul de editare să apară pe formă? Miroase a interpretor de cod! În fapt lucrurile sunt mult mai simple. Proprietatea Visible este declarată cu două metode private asociate, de citire si scriere a valorii proprietătii. Intern, înaintea compilării, preprocesorul substituie codul de mai sus cu un apel de metodă Editor.Show(true), care se ocupă de bucătăria afisării controlului. Proprietătile pot fi si vectori: elocvent este accesul la pixelii de pe device context cu proprietatea Canvas.Pixels[X,Y].

Utilizarea metodelor unei clase s-a diversificat cu două noi concepte. Metodele de clasă se declară cu prefixul class si sunt metode ale tipului de obiect si nu ale unei instante specifice a tipului respectiv de obiect. Se poate apela o astfel de metodă fără a mai fi nevoie să se instantieze un obiect.

Pentru implementarea conceptului de eveniment a fost necesară crearea notiunii de pointer de metodă, un tip procedural special care permite apelarea unei metode de obiect din afara obiectului si fără a se utiliza o referintă la obiect. Evenimentul unui component este de fapt un pointer la metoda formei-părinte ce contine cod specific de tratare a evenimentului respectiv.

Oarecum de asteptat este inovatia transmiterii de vectori deschisi (open arrays) ca parametri de functie sau procedură. Constructia vectorului se face acum chiar în apelul de procedură cu specificarea unui număr variabil de elemente. Borland a plusat permitând chiar specificarea de elemente de tip diferit în vector, facilitând astfel apelul de rutine de formatare de string-uri si, cu putină imaginatie chiar apeluri de functii în stil C.

Lista schimbărilor nu se încheie aici si poate fi consultată în caseta "Schimbări în Object Pascal". Nu voi conchide cu epitaful Pascal-ului pentru că, ceea ce de mult era de asteptat, handicapul ce transa orice dispută Pascal versus C, ultima barieră a căzut în cele din urmă:

Tratarea exceptiilor

Importanta tratării exceptiilor este covârsitoare si numai cei ce s-au aventurat în dezvoltarea unui proiect de anvergură fără a se asigura astfel au gustat din amărăciunea loviturilor pe la spate, gen depăsire de virgulă mobilă ce antrenează pierderea integrală a datelor... iar dacă au încercat să-si ia măsuri de protectie codul de validare a parametrilor si rezultatelor tindea să-l depăsească pe cel propriu-zis si antrena noi bug-uri.

Posibilitătile deschise de Delphi fac ca arhitectura unei aplicatii să devină foarte complexă si probabilitatea survenirii de exceptii să crească exponential, mai ales în medii de baze de date.

Tratarea exceptiilor se face conform unui concept hibrid între sistemul clasic de tratare structurată a exceptiilor si recunoasterea exceptiilor ca tipuri de obiecte. Codul susceptibil să întâlnească o eroare se include într-un bloc de protectie la care se atasează un alt bloc cu cod de tratare a exceptiilor suspectate. Blocul de tratare poate fi completat cu unul de terminare, tipic cu cod de făcut curătenie, care primeste controlul dar nu stinge exceptia. Exceptiile sunt diferentiate ca obiecte distincte derivate din tipul Exception si mostenesc codul necesar afisării unui mesaj formatat si conectării cu un help topic. Blocurile de protectie pot fi imbricate si controlul executiei revine la nivelul la care blocul de tratare recunoaste si interceptează tipul respectiv de exceptie.

Cea mai frecventă utilizare a blocurilor de protectie-tratare a exceptiilor se întâlneste când se doreste protejarea alocării de resurse. Adesea aparitia unei exceptii poate împiedica atingerea codului în care se efectuează eliberarea memoriei, închiderea de fisiere sau dealocarea de resurse Windows, cu consecinte imprevizibile pentru integritatea datelor sau stabilitatea sistemului. Includerea acestui cod - botezat cleanup code - într-un bloc de terminare garantează executia lui indiferent de aparitia exceptiei.

Invocarea unei exceptii este cea mai bună metodă si adesea singura pentru a "scăpa" din ramura de executie curentă. Spre exemplu, dacă în metoda ce tratează evenimentul BeforePost al unui obiect-tabelă se invocă o exceptie, actualizarea înregistrării curente în tabelă este anulată.

Tratarea exceptiilor nu este numai pentru programatorii profesionisti. Chiar dacă este complet ignorată de dezvoltator, protectia la exceptii încorporată în componentele din care s-a asamblat aplicatia blochează orice exceptie survenită fie din conditii externe, fie din erori de programare. Pur si simplu aplicatia nu crapă. Îsi revine până si din erori serioase precum General Protection Fault !

Delphi si Paradox

Paradoxul asocierii unui compilator cu un sistem de gestiune a bazelor de date este numai aparent. Desi un mediu RAD nu este obligatoriu si un mediu de dezvoltare de aplicatii de baze de date, nealinierea la cererea principală a pietii poate scoate din competitie cel mai performant sistem. Borland dispunea nu numai de atuul unui compilator remarcabil ci si de o tehnologie avansată de baze de date, completată în ultima vreme cu dezvoltarea Interbase SQL si achizitionarea lui ReportSmith. Iar cum produsul în care a investit cel mai mult se numeste Paradox, cu ce altceva decât Paradox putea să semene cel mai mult suportul de baze de date al lui Delphi!?

Delphi, intrinsec, nu are încorporat nici un fel de suport de baze de date. Totusi, componentele specializate în acces la baze de date livrate în standard sunt atât de complete încât transformă efectiv dezvoltarea unei forme într-o familiară editare de machetă cu tabele si query-uri în cele mai variate relatii de one-to-many, many-to-many, one-to-many-to-many-to...etc., cu controale din cele mai diverse, de la câmpuri de editare cu validare la câmpuri calculate, de la tabele cu editare in-place la câmpuri lookup combo box sau list box. Nu lipseste nici clasicul navigator cu butoane de înainte-înapoi, stergere, inserare, actualizare, etc.

Dezvoltatorul detine un control total asupra interactiunilor dintre utilizator si baza de date prin intermediul unui set complet de evenimente generate de obiecte dataset (tabele si query-uri) si datasource (interfată între dataset si câmpurile de editare). Există astfel posibilitatea de a efectua validări înainte de actualizarea modificărilor în tabelă, de a primi controlul înaintea inserării sau stergerii unei noi înregistrări sau la prima tentativă de modificare a înregistrării curente. Iar lista de posibilităti rămâne deschisă.

Cel mai bine se vor simti programatorii de Paradox care vor regăsi aceeasi filozofie în manipularea tabelelor prin operatiuni familiare precum Insert, Edit, Cancel, Post (Do_It), Next, First, Last, etc. Câmpurile unei înregistrări sunt accesibile ca obiecte componente distincte prin intermediul editorului de câmpuri al tabelei, existând tipuri distincte pentru fiecare format, inclusiv imagine, memo sau cîmp binar (BLOB). Adesea, singura operatiune cu câmpuri efectuată prin program este atribuirea sau citirea valorii unui câmp. Accesul se face prin intermediul proprietătii Value si mentinerea sincronizării câmpului cu controlul de editare asociat sau cu tabela se face automat prin metodele mostenite.

În spatele scenei se găseste o implementare deosebit de puternică a accesului la baze de date. Obiectul tabelă tratează în mod unitar atât o tabelă Paradox sau dBase cât si una SQL. Nu este necesară nici un fel de modificare în cod sau în proprietătile tabelei pentru a muta o aplicatie de pe o bază de date locală pe o bază de date echivalentă de pe un server SQL! Nu există de asemenea nici o limitare în lucrul simultan cu tabele provenind din surse diferite. Pe aceeasi formă pot coexista tabele SQL si un spreadsheet Excel provenind dintr-o sursă ODBC. Remarcabilă este si aducerea la un numitor comun a diverselor specii de index, programatorul utilizând transparent un index secundar Paradox, un index DBase sau unul SQL.

Întrucât editoarele de componente nu dispun de facilităti de creare, editare sau interogare de baze de date în scopuri de testare a aplicatiilor, Delphi este însotit de Database Desktop - un Paradox miniatural capabil să creeze si restructureze tabele Paradox si DBase dar si SQL, fără capabilităti de forme si rapoarte - evident.

SQL - cuvântul la modă

Doar utilizarea tabelelor, chiar cu filtre si legate în relatii complexe, nu mai satisface adesea nici măcar în scopuri de editare. Iar a interoga navigând prin tabele si testând relatii a devenit nu numai desuet si neproductiv dar chiar generator de bug-uri.

Utilizarea obiectele tip TQuery deschide perspective remarcabile către cele mai diverse scheme de prelucrare sau editare a datelor. Query-urile sunt în esentă obiecte de executie a unei comenzi SQL asupra unor tabele putând proveni din surse eterogene, Paradox, DBase, ODBC sau servere SQL diferite. Fiind un descendent al tipului TDataset, query-ul are numeroase trăsături comune cu tabela, putând fi integrat în relatii, navigat, chiar editat în anumite conditii când se comportă ca un dynaset si actualizează tabelele de provenientă a datelor. Evident, comenzile SQL admit variabile care permit schimbarea dinamică a rezultatelor query-ului si chiar legarea query-ului de valori din înregistrarea curentă a altei tabele sau query.

Un obiect specializat în copierea si adăugarea de dataset-uri, TBatchMove, permite înlăntuirea query-urilor atunci când nu se poate ajunge la rezultatul dorit printr-o singură interogare SQL.

Dezvoltatorii nefamiliari cu SQL pot folosi Database Desktop pentru a construi vizual un query-by-example pe care îl pot traduce apoi în comandă SQL si integra în obiectul query, dacă nu sunt cumva fericitii posesori ai versiunii client-server care include un editor vizual de query-uri. Nu orice QBE se poate traduce în SQL si invers.

Utilizarea de query-uri reduce dramatic timpul de dezvoltare a unei baze de date si crează premize spre migrarea acesteia spre suport SQL. Folosirea lui pe baze de date locale simplifică dezvoltarea dar abuzul se plăteste scump. Astfel, crearea un obiect query necesită cam 100 KBytes de memorie, în timp ce un obiect tabelă se multumeste cu câtiva KBytes.

Cine este responsabil de interpretarea si executia query-ului, ca si de acces la baze de date în general? Borland si-a bazat toate produsele, de la Paradox la Delphi pe al său Borland Database Engine (o implementare a standardului IDAPI - alternativă viabilă la ODBC-ul lui Microsoft). Prin BDE este posibil accesul atât la surse native cum sunt Paradox si dBase precum si la conexiuni ODBC, pentru care interpretează si execută comenzile SQL, cât si la servere SQL, cărora le transmite cererile SQL si optimizează modul de acces la rezultate. Din punct de vedere al performantei pe baze de date locale, driver-ele native Paradox si DBase sunt net mai rapide decât cele similare disponibile prin ODBC, astfel încât acesta din urmă rămâne doar ca alternativă de conectare la formate mai ciudate de tabele.

Dornic să apelez direct functii BDE am descoperit - nedocumentată bineînteles - interfata de programare BDE (fisierele dbiprocs.int, dbierrs.int, dbitypes.int). Desi căutam numai o functie de actualizare a cache-ului pe disc am descoperit stupefiat functii de un nivel foarte înalt de operare cu query-uri, seturi de date, tranzactii, operatiuni de tip batch, stabilire de relatii, sortare, s.a.m.d. Se explică astfel capabilitătile remarcabile ale obiectelor tabelă si query din Delphi, care nu sunt decât simple împachetări obiectuale ale functionalitătii unui motor de baze de date foarte avansat. Aplicatiile Delphi au în spate performanta nativă a Paradox-ului si DBase-ului for Windows.

Desi oferta este covârsitoare, Borland plusează din nou integrând si Local Interbase Server - o versiune locală de server SQL, mono-utilizator si multi-instantă, în scopul declarat de testare locală de aplicatii Delphi pe baze de date SQL înaintea scalării acestora pe servere reale Interbase, Oracle, Sybase sau Informix.

M-am întrebat desigur cam ce monstruozitate va trebui distribuită clientului si pe cîte CD-uri? Ei bine, o aplicatie tipică de baze de date cuprinde un executabil selfconsistent de 500-700 KBytes si motorul de baze de date BDE, care ocupă 3 MBytes cu totul din care vreo 800 KBytes utili. În rulare, o aplicatie complexă MDI cu sase-opt forme de date deschise simultan nu consumă mai mult de un megabyte din memoria disponibilă, incluzând si cache-ul BDE, si galopează pe un 386SX cu 4 MBytes de RAM. Cu asemenea cerinte Intel si-ar pierde repede pâinea. Noroc cu Microsoft...

Eternele rapoarte

Iată un domeniu care îmi displace profund. În enciclopedia galactică, la capitolul specii dispărute, despre omenire se va mentiona că a sucombat sufocată în hârtii. Iar solutia găsită de Borland, purtând nefericitul nume de ReportSmith (forjorul de rapoarte!) este în perfect acord cu cele de mai sus.

Dacă doriti să scăpati repede de sarcina ingrată a listării de rapoarte, RS este o solutie dar - să sperăm - una pe termen scurt. Editorul de query este pe cât de facil pe atât de simplist, încât de cele mai multe ori preferi să elaborezi direct interogarea SQL. Adăugarea de câmpuri calculate devine un chin înfiorător care presupune scrierea de macro-uri criptice în Basic, ca de altfel orice automatizare doresti s-o adaugi. Si nu în cele din urmă, desenarea vizuală a raportului este o sarcină penibilă cu instrumente si functii primitive. Iar portarea fontului draft de imprimantă între diverse driver-e de imprimante se face după filozofia Microsoft: fonturile True-Type înainte de toate!

Adăugarea sistemului de rapoarte la aplicatia de baze de date se realizează cu RS Runtime, care poate fi pilotat prin DDE din programul Delphi. Dintr-o dată, necesarul de câteva sute de KBytes de RAM al aplicatiei creste la câtiva MBytes în momentul listării raportului. Iar distributia se măreste si ea cu opt Mbytes... Ce mai, o sculă demnă de Visual Basic!

Compromisuri

După un an si jumătate de dezvoltare si încă pe atât de beta-testare Borland a livrat un produs remarcabil, destinat realizării de aplicatii vitale pentru un sistem de operare recunoscut pentru limitările si instabilitatea sa. Dincolo de paleta bogată de facilităti pe care o posedă, Delphi asigură aplicatiilor produse o exceptională stabilitate si sigurantă în rulare, mediul însusi bucurându-se de o fiabilitate remarcabilă: în cîteva sute de ore de dezvoltare si depanare nu a crăpat niciodată!

Cum nimeni si nimic nu este perfect, realizatorii lui Delphi mai au numeroase deziderate de satisfăcut si numai viitorul va confirma capacitatea lor de a-si sustine si perfectiona produsul.

Compilatorul generează în continuare numai cod pe 16 biti. Optiunea de compilare de ocolire a erorii din coprocesorul Pentium-ului nu are nimic de-a face cu optimizări de cod pentru Pentium. Instructiunile pe 16 biti antrenează o reducere la jumătate a performantei potentiale în prelucrarea întregilor pe 32 biti precum si în operatiunile intensive cu memoria, iar noile tipuri de obiecte se alocă toate în memoria dinamică!

Subsetul limbajului SQL pentru interogarea tabelelor în format Paradox si DBase este handicapat de limitări drastice, care sunt de dorit să dispară, ca si lipsa suportului pentru operatiuni tranzactionale pe aceleasi tabele.

Delphi a fost conceput din start ca un mediu neechilibrat: face totul pentru dezvoltatorii de aplicatii si nimic pentru programatorii de obiecte. Nici documentatia nu îi sustine pe acestia din urmă, pentru atingerea de scopuri profesionale fiind obligatorie achizitionarea de referinte de limbaj si documentatii suplimentare ca si de sursele bibliotecii de componente. Însăsi modul categoric de departajare al utilizatorilor de Delphi în dezvoltatori si programatori ar putea înregistra un esec răsunător dacă Windows-ul lui Microsoft nu se axează pe aceasi directie extinzând dihotomia la întregul sistem de operare. În ceea ce priveste suportul OLE, Borland a gresit în trecut nealiniindu-se la Microsoft: va gresi acum tinându-se prea aproape?

Delphi rămâne totusi o experientă necesară, măcar pentru a încerca si altfel.


(C) Copyright Computer Press Agora