Algoritmi pentru generarea de coduri

Generarea de coduri cu programare folosind platforma Microsoft.NET

introducere
Generarea de coduri "pe frunte"
Generarea de coduri utilizând șabloane
Generarea de coduri folosind șabloane XSLT
Generarea de coduri folosind ASP.NET
Generarea de coduri în mai multe limbi
Generarea de coduri în mai multe limbi folosind șabloanele CodeDOM
Generarea codului de execuție

Algoritmi pentru generarea de coduri

Nu este un secret faptul că, uneori, atunci când programați o sarcină, trebuie să efectuați o mare cantitate de muncă obișnuită de rutină și nu puteți scăpa de ea utilizând instrumentele obișnuite ale OOP. În plus, situația este exacerbată de lipsa tipurilor de generice .NET în limbi.

În .NET Framework, generarea de coduri este de asemenea folosită destul de des. De exemplu, folosind generatorul de cod bazat pe XSD-fișier cu schema de date sunt seturi de date (seturi de date tastate) tastat, crea clase proxy pentru servicii Web folosind generatorul de cod. În timpul rulării, generarea de cod pentru a îmbunătăți clase de performanță System.Xml.Serialization.XmlSerializer, System.Text.RegularExpressions.Regex, System.Web.UI.PageParser.

Generarea de coduri "pe frunte"

Primul lucru care vine de obicei în minte este generarea codului în orice limbaj de programare "direct". Să presupunem că este necesară generarea unei clase printr-o descriere a unui set de proprietăți. Setați descrierea ca fișier xml:

Această descriere va fi într-una din ansamblurile de proiect ca o resursă.

Pentru a reprezenta structura clasei în cadrul programului, vom crea un set de clase cu care va funcționa algoritmul de generare a codurilor. Pentru a nu crea manual o reprezentare obiect din xml, vom folosi clasa XmlSerializer.

Clasa XmlSerializer este un serializator de obiecte în xml. În acest caz, spre deosebire de formatul emis de SoapFormatter, în acest caz, format XML se pretează la o inspecție mai amănunțită. În special, următorul exemplu este dat de atributul name atributul tag XmlRoot rădăcină XmlAttribute date proprietățile de conservare în valoarea atributului cu numele specificat, atributele și XmlArray XmlArrayItem mod de prezentare tablouri si liste.

Și, deși "semnificația" funcției nu sa schimbat, ea a devenit mai scurtă și, cel mai important, mult mai clar atunci când a citit. În cazul în care există o mulțime de text static, de exemplu, în cazul colecțiilor tipizate, această abordare este mult mai convenabilă decât prima. Cu toate acestea, în exemplul nostru, a existat o mulțime de cod manual în generatorul de coduri. Principalul motiv pentru aceasta este necesitatea de a efectua iterații manual. Ar fi bine să specificați această iterație direct în șablon. Puteți scrie, bineînțeles, procesorul macro adecvat, dar vom merge invers. Utilizăm soluții gata făcute.

Generarea de coduri folosind șabloane XSLT

Una dintre soluțiile pregătite pentru crearea de șabloane face parte din XS3T XSLT XSLT transformare standard XS3 - XSL. Această tehnologie este concepută pentru a converti fișiere xml într-o altă vizualizare și are o flexibilitate foarte mare.

XSLT este un limbaj de programare optimizat în scopul specificării regulilor de conversie. Fișierul XSLT constă dintr-un set de reguli notate de etichetele șablonului. Spre deosebire de limbile clasice, XSLT descrie transformarea nu ca o secvență de acțiuni, precum și un set de reguli care se aplică la nodurile fișierului XML de intrare. Fiecare regulă conține o funcție logică, predicatul, imaginind pe care le poate determina dacă este potrivit pentru nodul curent. În cazul XSLT, o limbă specială, XPath, este utilizată pentru a descrie astfel de funcții. Dacă predicatul returnează true, conținutul regulilor este realizată, care constă din text static și un set de tag-uri care seamănă cu limbaje logice de sintaxă - .. valori de timbre stare de buclă, etc. În plus, eticheta aplică-șabloane este specificat pentru imbricate continua nodurile de procesare. Fișierul este procesat pornind de la nodul rădăcină.

O descriere completă a XSLT poate fi găsită pe site-ul web al Consorțiului World Wide Web, www.w3c.org

Totul, generatorul de coduri este gata.

Generarea de coduri în mai multe limbi

Platforma Microsoft.NET acceptă programarea în mai multe limbi. Dacă este important nu doar să obțineți rezultatul final, ci să obțineți codul sursă în diferite limbi de programare, este, de asemenea, foarte dorit să aveți sprijinul mai multor limbi. Cu toate acestea, exemplele anterioare de generatoare de cod pentru adăugarea suportului de limbă necesită fie rescrierea completă, fie cel puțin în redesignul complet al șabloanelor. Pentru a rezolva această problemă, Microsoft oferă tehnologia CodeDOM.

Procesul de generare a codului folosind această tehnologie este după cum urmează. Mai întâi, se construiește un arbore al construcțiilor sintactice generalizate ale limbajului, care apoi este transformat într-un cod sursă de către furnizorul CodeDOM al unei anumite limbi.

Să încercăm să implementăm generatorul de coduri din primul exemplu folosind CodeDOM.

Generatorul de coduri pentru Visual Basic.NET va returna următorul cod:

Dar este ușor de observat că doar exemplul de mai sus are același dezavantaj cu care ne-am luptat în întregul articol, și anume generarea de statice părți (neschimbătoare) ale codului. Din păcate, aceste abordări pe care le-am folosit pentru a face acest neajuns, în cazul configurației în mai multe limbi nu mai este adecvat.

Generarea de coduri în mai multe limbi folosind șabloanele CodeDOM

Este clar că în acest caz, modelul de generare ar trebui reprezentat ca un arbore CodeDOM. Întrebarea este doar cum să o obținem. Puteți, desigur, să dezasambleze codul sursă în C # la fel, dar un astfel de limbaj de parsare - nu este ușor, și nu toate modelele de C # pot fi exprimate în CodeDOM.

Prin urmare, ca limbă pentru descrierea șabloanelor CodeDOM, folosim o limbă cu un parser pregătit - XML.

Din nefericire, în cadrul acestui articol este imposibil să implementăm parserul de descriere XML al CodeDOM, ținând cont de toate capabilitățile sale, deci implementăm doar partea necesară pentru implementarea exemplului. Pentru implementare, vom folosi aceeași metodă pe care am descărcat-o de date originale, adică XmlSerializer. Pentru clasele care reprezintă elementele unui șablon, definim o clasă de bază abstractă:

Declarăm în el o metodă virtuală care va returna elementul corespunzător al elementului șablon CodeDom. Codul sursă complet pentru clasele de descărcat de pe xml se află pe CD-ROM-ul care însoțește jurnalul.

Acum implementați șablonul. Deoarece atât datele de intrare, cât și cele de ieșire sunt exprimate în XML, vom folosi transformarea XSLT.

Folosind o tehnică similară, puteți implementa algoritmi foarte eficienți care sunt optimizați pentru date specifice. Performanța la punerea în aplicare competentă a generării de cod este comparabil cu punerea în aplicare manuală completă a algoritmilor de date specifice. De exemplu, viteza de deserializing structura XmlSerializer copac este în esență aceeași ca și citirea manuală a XMLReader și semnificativ (de 2-3 ori) viteza SoapFormatter mai mare folosind algoritmul universal și mecanismul de reflexie (reflexie). Viteza de ASP.NET, folosind un cod generație pentru algoritmi complecși considerabil mai mari viteze ASP folosind interpretare.

Cu toate acestea, exemplul de mai sus are și un dezavantaj, în unele cazuri semnificativ. Compilarea din sursă este un proces foarte lent. Puteți observa acest lucru, de exemplu, pentru o întârziere semnificativă în încărcarea unei pagini aspx atunci când este schimbată. Dar în acest caz există o cale de ieșire - .NET Framework permite crearea de ansambluri simultan în codurile IL.

Când generați un ansamblu, îl puteți descărca din memorie numai atunci când descărcați întregul domeniu. Prin urmare, cu regenerarea frecventă a ansamblului, este mai bine să creați într-un domeniu separat și să descărcați acest domeniu imediat ce dispare nevoia acestuia.

Generarea codului direct în codul IL

Pentru a crea ansambluri on-the-fly, mecanismul de reflecție oferă un set de capabilități alocate spațiului de nume System.Reflection.Emit. Vom încerca să generăm clasele imediat în ansamblu, ocolind generarea și compilarea codului sursă.

concluzie

Exemplele de mai sus arată cum se construiesc sisteme flexibile și foarte adaptabile utilizând generarea de coduri, care nu sunt limitate de capacitățile limbilor utilizate.

Din păcate, generarea de coduri are un dezavantaj serios - rezultatul generării codului nu poate fi schimbat. Recent, cu toate acestea, piața există sisteme care pot genera nu numai codul din structura de date, dar, de asemenea, pentru a converti codul înapoi la datele originale. Acest lucru este realizat prin parsarea codul generat și compararea structurilor originale și copacii care rezultă din detectarea manuală se schimbă, astfel încât mai târziu, în generația următoare, să ia în considerare aceste schimbări. Cel mai probabil, pentru astfel de sisteme viitorul.

Articole similare