Reinvestirea Profitului Unei Firme In Baza Materiala
Reinvestirea profitului unei firme în baza materială
Cuprins
introducere
1. tehnologii folosite
1.1. Arhitectura .NET
1.1.1. Framework-ul .NET
1.1.2. Componente ale lui .NET Framework și arhitectura acestuia
1.1.3. Compilarea programelor
1.1.4. De ce am alege .NET?
1.2. Introducere în limbajul C#
1.2.1. Caracterizare
1.2.2. Structura unui program C#
1.2.3. Tratarea excepțiilor în C#
1.3. Principiile programării orientate pe obiect
1.3.1. Principiile programării orientate pe obiect
1.3.2. Moștenirea
1.3.3. Polimorfism
1.4. ADO.NET
1.4.1. Arhitectura ADO.NET
1.4.2. Furnizori de date în ADO.NET
1.4.3. Connection
1.4.4. Command
1.4.5. DataReader
1.4.6. DataAdapter
1.5. Tehnologii SMTP(Simple Mail Transfer Protocol)
1.5.1. Ce este SMTP?
1.5.2. Clasa MailAddress
1.5.3. Clasa SmtpClient
1.5.4. Clasa MailMessage
1.6. Algoritmi
1.6.1. Algoritmul Greedy
2. Fundamente – sql server
2.1. Sql Server
2.1.1. Scurtă introducere
2.1.2. Arhitectura client/server pe trei niveluri și avantajele acesteia
2.1.3. Modelarea datelor
2.1.4. Normalizarea bazelor de date
3. Aplicație: Dezvoltarea aplicativă
3.1. Descrierea aplicației
3.1.1. Motivul aplicației
3.2. Paginile aplicației
3.2.1. Logarea în aplicație
3.2.2. Cautarea și introducerea datelor
3.2.3. Fereastra Calculator
3.2.4. Fereastra Export Date
3.2.5. Fereastra Ajutor
anexe
bibliografie
Introducere
Această lucrare reprezintă proiectul meu de licentă în cadrul Universității din Pitești, al facultății de Matematica-Informatică.
În cadrul facultății am învățat să pun în practică cunoștințele dobândite în cei trei ani de facultate, dar și lucruri noi sau de aprofundare.
În primul capitol al lucrării sunt prezentate tehnologiile folosite în cadrul aplicației: Arhitectura .NET, o scurtă introducere ăn limbajul C#, principiile programării orientate pe obiect, ADO.NET, tehnologii SMTP(Simple Mail Transfer Protocol), precum și algoritmi folosiți.
În cel de-al doilea capitol am discutat despre SQL Server, un program de baze de date precum și despre arhitectura client/server pe trei niveluri și avantajele acesteia, modelarea datelor și normalizarea bazelor de date.
Al treilea capitol reprezintă un manual de utilizare, în care sunt descrise acțiunile utilizatorului în cadrul folosiriii aplicației, sunt detaliate aspecte privind dezvoltarea și organizarea aplicației, cea mai importantă secțiune fiind modul de calculare și selectie al produselor. Tot în acest capitol se face o analiză a modului de structurare a datelor folosite de aplicație, precum și o analiză a modului de concepere a aplicației, prezentând problemele de implementare, principalele funcționalitățti ale aplicației și cele mai importante părți din codul aplicației.
Capitolul 1.
Tehnologii folosite
1.1. Arhitectura .NET
1.1.1. Framework-ul .NET
Tehnologia .NET pune laolaltă mai multe tehnologii(ASP, XML, OOP, SOAP, WDSL, UDDI) și limbaje de programare (VB, C++, C#, J#) asigurând, totodată, atât portabilitatea codului compilat între diferite calculatoare cu sisteme Windows, cât și reutilizarea codului în programe, indiferent de limbajul de programare utilizat.
.NET Framework este o componentă livrată împreună cu sistemul de operare Windows. Ultima versiune .NET Framework 4.6 RC a fost lansată pe 12 noiembrie 2014, ea vine instalată pe Windows 10 și poate fi instalată pe versiunile Windows 8.1, Windows 8, Windows 7 SP1 și Windows Vista SP2.
Platforma .NET constă în cateva grupe de produse:
Unelte de dezvoltare:
un set de limbaje (C#, Visual Basic .NET, Managed C++, Smalltalk, Perl, Fortran, Cobol, Lisp, Pascal etc),
un set de medii de dezvoltare (Visual Studio .NET, Visio),
o bibliotecă de clase pentru crearea serviciilor Web, aplicațiilor Web și aplicațiilor desktop Windows.
Servere specializate − un set de servere Enterprice .NET: SQL Server 2014, SQL Server 2012, SQL Server 2008 R2, Exchange 2007, BizTalk Server 2006, SharePoint, etc, care pun la dispoziție funcționalitățti diverse pentru stocarea bazelor de date, email, aplicații B2B (Bussiness to Bussiness – comerț electronic între partenerii unei afaceri).
Servicii Web – utile în aplicații care necesită identificarea utilizatorilor (de exemplu, .NET Passport – un mod de autentificare folosind un singur nume și o parolă pentru toate site-urile vizitate).
Dispozitive – noi dispozitive non-PC, programabile prin .NET Compact Framework, o versiune redusă a lui NET FrameworkȘ Pocket PC Phone Edition, Smartphone, Tablet PC, Smart Display, Xbox, etc.
1.1.2. Componente ale lui .NET Framework și arhitectura acestuia
Figura 1.1. Arhitectura .NET
Componenta .Net Framework este formată din compilatoare, biblioteci și alte executabile utile în rularea aplicațiilor .NET. Figura 1.1. schematizează arhitectura platformei .NET care cuprinde cateva din următoarele componente:
Common Language Runtime (CLR): este de departe cea mai importanta componentă a lui .NET Framework. Este responsabilă cu managementul și execuția codului scris în limbaje .NET, aflat în format CIL; este foarte similar cu Java Virtual Machine. CLR instanțiază obiectele, face verificări de securitate, depune obiectele în memorie, și disponibilizează memoria prin garbage collection.
Common Type System (CTS): asigură cooperarea limbajelor din platforma .NET, o clasă scrisă in limbajul C# trebuie să fie echivalentă cu una scrisă in VB.NET, o interfată scrisă in Managed C++ trebuie să fie perfect utilizabilă în Managed Cobol. Toate limbajele trebuie să recunoască și sa poată manipula niște tipuri comune ca: Tipuri valoare, Tipuri referință, Boxing și unboxin, clase, indexatori, proprietăți, interfețe, delegați.
Metadate: înseamnă “date despre date”, pe baza acestora, CLR știe cum să instanțieze obiectele, cum să apeleze metodele și cum sa acceseze proprietățile.
Assemblies: reprezintă un bloc funcțional al unei aplicații . NET, care formează unitatea fundamentală de destribuire, versionare, reutilizare și premisiuni de securitate. Un asembly conține metadate care sunt folosite de către CSR, scopul acestor “assemblies” este să asigure dezvoltare softului în mod “plug-and-play”.
Assembly cache: atunci când un assembly este instalat pe o mașină , el va fi adăugat în assembly cache. Dacă programul de instalare este scris corect, va evita suprascrierea assembly-urilor deja existente și care funcționează perfect cu aplicațiile instalate, adaugând doar noul assembly.
Garbage collection: este mecanismul care se declanșează atunci când alocatorul de memorie răspunde negativ la o cerere de alocare de memorie. Implementarea este de tip “mark and sweep”: se presupune initial că toată memoria alocată se poate disponibiliza, dupa care se determină care din obiecte sunt referite de variabilele aplicției; cele care nu mai sunt referite sunt dealocate, iar celelalte zone de memorie sunt compactate.
1.1.3. Compilarea programelor
Un program scris într-unul dintre limbajele .NET conform Common Language Specification (CLS) este compilat în Microsoft Intermediate Language (MSIL sau IL). Codul astfel obținut are extensia “exe”, dar nu este direct executabil, ci respectă formatul unic MSIL.
CLR include o mașină virtuală asemănătoare cu o mașină Java, ce execută instrucțiunile IL rezultate în urma compilării. Mașina folosește un compilator special JIT (Just in Time). Compilatorul JIT analizează codul IL corespunzător apelului unei metode și produce codul mașină adecvat și eficient. El recunoaște secvențele de cod pentru care s-a obținut deja codul mașină adecvat, permițând reutilizarea acestuia fără recompilare, ceea ce face ca, pe parcursul rulării, aplicațiile .NET să fie din ce în ce mai rapide.
Faptul că programul IL produs de deiferite limbaje este foarte asemănător are ca rezultat cooperare între aceste limbaje. Astfel, clasele și obiectele create într-un limbaj specific .NET pot fi utilizate cu succes în altul.
În plus, CLR se ocupă de gestionarea automată a memoriei (un mecanism implementat în platforma .NET fiind acela de eliberare automată a zonelor de memorie asociate unor date devenite inutile – Garabage Collection).
Cu un element de portabilitate, trebuie spus că .NET Framework este implementarea unui standart numit Common Language Infrastructure, ceea ce permite rularea aplicațiilor .NET, în afară de Windows, și pe tipurile de Unix, Linux, Solaris, Mac OS X și alte sisteme de operare.
1.1.4. De ce am alege .NET?
În primul rand pentru că ne oferă instrumente pe care le putem folosi și în alte programe, oferă acces ușor la baze de date, permite realizarea desenelor sau a altor elemente grafice. Spațiul de nume System.Windows.Forms conține instrumente (controale) ce permit implementarea elementelor interfeței grafice cu utilizatorul. Folosind aceste controale, puteți proiecta și dezvolta rapid și interactiv, elementele interfeței grafice. Tot .NET vă ofera clase care efectuează majoritatea sarcinilor uzuale cu care se confruntă programele și care plictisesc și fură timpul programatorilor, reducând astfel timpul necesar dezvoltării aplicațiilor.
1.2. Introducere în limbajul C#
1.2.1.Caracterizare
Limbajul C# a fost dezvoltat de o echipă restrânsă de ingineri de la Microsoft, echipă din care s-a evidențiat Anders Hejlsberg (autorul limbajului Turbo Pascal și membru al echipei care a proiectat Borland Delphi).
C# este un limbaj simplu, cu circa 80 de cuvinte cheie și 12 tipuri de date predefinite. El permite programarea structurată, modulară și orientată obiectual, conform conceptelor moderne ale programării profesioniste, dar și învățarea foarte ușoară a acestui limbj deoarece sintaxa limbajului va fi imediat recunoscută de dezvoltatorii familiarizați cu limbajele C, C++ și Java.
Elementele fundamentale ale programării orientate pe obiecte (ÎNCAPSULARE, MOȘTENIRE, POLIMORFISM) reprezintă una din mariile principii de bază ale programării în C#, care permite dezvoltatorilor să construiască o varietate de aplicații sigure și robuste care rulează pe .NET Framework. Sintaxa limbajului C# simplifică multe din complexitatea C++ și oferă caracteristici puternice, cum ar fi tipurile de valoare nulă, delegări, expresii lambda și acces direct la memorie, care nu se gasesc în Java, unele funcii fiind diversificate (tipul struct) , modificate (tipul string) sau chiar eliminate (moștenirea multiplă și pointerii către funcții) toate acestea având ca scop realizarea unor secvențe de cod sigure (safe).
În plus față de toate aceste principii orientate pe obiecte, C# facilitează dezvoltarea componentelor software prin construirea mai multor limbi inovatoare, precum următoarele:
Semnături de metode incapsulate numite de delegari, care permit notificări de evenimente de tip sigur (safe).
Proprietăți, care servesc drept accesorii pentru variabilele membre private.
Atribute, care oferă metadate declarative despre tipurile de la momentul execușiei.
Documente XML comentate în linie.
Limbajul integrat Query (LINQ), care ofera posibilitatea de interogare “built-in” pe o varietate de surse de date.
1.2.2.Structura unui program C#
Structura unui program C# este formată din una sau mai multe clase, care la randul lor sunt grupate în spații de nume (namespace), fiind obligatoriu ca doar una din aceste clase să conțină un “punct de intrare” (entry point), si anume metoda (funcția) Main.
Figura 1.2. Structura unui program C#
Clasa (class), în termeni simplificați, reprezintă tipul referintă, care poate să moștenească o singură clasă și poate implementa mai multe interfețe. Clasele reprezintă principalul element structural și de organizare în limbjele orientate pe obiecte, grupând date cât și funcții care prelucrează respectivele date, fiecare membru putând conține un nivel de protecție, care controlează gradul de acces la el.
Spațiul de nume (Namespace), este folosit pentru a declara un domeniu de aplicare care conține un set de obiecte legate. În general este utilizat pentru a organiza elementelatoare, precum următoarele:
Semnături de metode incapsulate numite de delegari, care permit notificări de evenimente de tip sigur (safe).
Proprietăți, care servesc drept accesorii pentru variabilele membre private.
Atribute, care oferă metadate declarative despre tipurile de la momentul execușiei.
Documente XML comentate în linie.
Limbajul integrat Query (LINQ), care ofera posibilitatea de interogare “built-in” pe o varietate de surse de date.
1.2.2.Structura unui program C#
Structura unui program C# este formată din una sau mai multe clase, care la randul lor sunt grupate în spații de nume (namespace), fiind obligatoriu ca doar una din aceste clase să conțină un “punct de intrare” (entry point), si anume metoda (funcția) Main.
Figura 1.2. Structura unui program C#
Clasa (class), în termeni simplificați, reprezintă tipul referintă, care poate să moștenească o singură clasă și poate implementa mai multe interfețe. Clasele reprezintă principalul element structural și de organizare în limbjele orientate pe obiecte, grupând date cât și funcții care prelucrează respectivele date, fiecare membru putând conține un nivel de protecție, care controlează gradul de acces la el.
Spațiul de nume (Namespace), este folosit pentru a declara un domeniu de aplicare care conține un set de obiecte legate. În general este utilizat pentru a organiza elementele de cod și de a crea tipuri globale unice. Fiecare mulțime de definișie dintr-o librărie sau program este grupată într-un spațiu de nume, existând astfel posibilitatea de a avea într-un program definiții cu nume identic, dar situate în alte spații de nume. În cazul în care, într-o aplicație, unele clase sunt deja definite, ele pot folosi importând spațiile de nume care conțin definițiile acestora.
1.2.3.Tratarea excepțiilor în C#
C#, la fel ca alte limbaje de prgramare, perimite tratarea erorilor și a situațiilor deosebite prin excepții. O excepție este un obiect care încapsulează informații despre o situație anormală. Ea este folosită pentru a semnala contextul în care apare acea situație deosebită. Când o metodă întalnește o situație specială, se va ”arunca” o excepție care trebuie sesizată și tratată, aruncarea excepțiilor realizandu-se cu ajutorul instrucțiunii throw. Prinderea și tratarea excepțiilor se face cu ajutorul blocului catch. C# permite existența mai multor blocuri catch, fiecare dintre are având rolul de a prinde și trata o excepție.
Pentru a garanta că un anumit cod se va executa indiferent daca totul decurge normal sau apare o excepție, acest cod se va pune în blocul finally care se va executa în orice situație.
Un programatoe nu trebuie să confunde tratarea excepțiilor cu erorile sau bug-urile. Un bug este o eroare de programare care ar trebui să fie fixată înainte de livrarea codului. Excepții nu sunt gandite pentru a preveni bug-urile (cu toate ca un bug poate să ducă la apariția unei excepții), pentru că acestea din urmă ar fi trebuit să fie eliminate.
Chiar dacă programatorul elimină toate bug-urile din programul său pot apărea erori pe care el nu le poate preveni:
încercarea de deschidere a unui fișier inexistent
împărțiri la zero
etc.
În cazul în care o metodă întalneșste o astfel de excepție, atunci respectiva excepție va trebui ”prinsă” în vederea tratării (rezolvării) ei.
Tipul Exception
În C# se pot arunca ca excepții obiecte de tip System.Exception sau derivate ale lui. Pe lângă ierarhia de excepții pe care limbajul C# o are inclusă, programatorul își poate crea propriile sale tipuri excepție.
Figura 1.3. Ierarhia excepțiilor
Enumerăm câteva din metodele și proprietățile relevante ale clase Exception ar fi:
public Exception(), public Exception(string), public Exception(string, Exception) – constructori; ultimul preia un obiect de tip Exception (sau de tip clasă derivată) care va fi încapsulat în instanța curentă; o excepție poate deci să conțină în interiorul său o instanță a altei excepții (cea care a fost de fapt semnalată inițial).
public virtual string HelpLink {get; set;} obține sau setează o legatură către un fisier help asociat acestei excepții; poate fi de asemenea o adresă Web (URL).
public Exception InnerException {get;} returnează excepția care este încorporată în excepția curentă.
public virtual string Message {get;} obține un mesaj care descrie excepția curentă
public virtual string Source {get; set;} obține sau setează numele aplicației sau al obiectului care a cauzat eroarea
public virtual string StackTrace {get;} obține o reprezentare string a apelurilor de metode care au dus la apariția acestei excepții.
Public MethodBase TargetSite {get;} obține metoda care a aruncat excepția curentă.
Blocuriel try și catch
POO oferă o soluție pentru gestionarea erorilor: folosilea blocurilor try și catch. În scrierea codului, programatorul ca separa acele instrucțiuni care sunt sigure (adică nu pot fi generatoare de excepții), de cele care sunt susceptibile să conducă la erori. Partea de program care poate genera excepții o vom plasa într-un bloc try, iar partea corespunzătoare tratării excepției, într-un bloc catch.
În cazul în care blocul try generează o excepție, Runtime întrerupe execuția și caută un bloc catch apropiat care, în funcție de tipul său să poată trata respectiva eroare. În cazul în care este găsit respectivul bloc catch programul continuă cu instrucțiunile din corpul catch. În cazul în care nu se găsește nici un catch corespunzător, execuția programului este întreruptă.
Instrucțiunea throw
Această instrucțiune este folosita pentru ai oferi programatorului posibilitatea să-și compună modalități proprii de aruncare a erorilor. Exemplu:
Figura 1.4. Aruncarea unei excepții folosind instrucțiunea throw
Aruncarea unei excepții oprește execuția metodei curente, dupa care CLR începe să caute un manipulator de excepție. Dacă un handler de excepție nu este gasit în metoda curentă, atunci CLR ca curăța stiva, ajungându-se la metoda apelantă. Fie undeva în lanțul de metode care au fost apelate se găsește un excepțion handler, fie thread-ul curent este terminat de către CLR.
Instrucțiunea finally
Limbajul C# permite ca la ieșirea dintr-un bloc try să fie executate obligatoriu anumite instrucțiuni, în cazul în care programatorul dorește acest lucru. Pentru acest lucru, respectivele instrucțiuni vor fi plasate într-un bloc finally.
Blocul finally este util fie pentru a evita scrierea unor instrucțiuni de mai multe ori, fie pentru a elibera resursele după părăsirea excepției.
Uneori, aruncarea unei excepții și golirea stivei până la blocul de tratare a excepției poate să nu fie o idee bună. De exemplu, dacă excepția apare atunci când un fișier este deschis (și închiderea lui se poate face doar în metoda curentă), atunci ar fi util ca să se închidă fișierul înainte ca să fie preluat controlul de către metoda apleată. Astfel supus, ar trebui să existe o garanție că un anumit cod se va executa, indiferent daca totul merge normal sau apare o excepție. Acest lucru se face prin intermediul blocului finally, care se va executa în orice situație. Existența acestui bloc elimină necesitatea existenței blocurilor catch (cu toate că și acestea pot să apară).
1.3. Principiile programării orientate pe obiecte
1.3.1. Principiile programării orientate pe obiecte
Ideea programării orientate pe obiecte este de a cea programele ca o colecție de obiecte, unități individuale de cod care interacționează unele cu altele, în loc de simple liste de instrucțiuni sau de apleuri de proceduri.
Obiectele POO sunt, de obicei, reprezentări ale obiectelor din viața reală (domeniul problemei), astfel încât programele realizate prin tehnica POO sunt mai ușor de înteles, de depanat și de extins decât programele procedurale. Aceasta este adevărată mai ales în cazul proiectelor software complexe și de dimensiuni mari.
Principiile POO sunt:
Abstractizarea – principiul care permite identificarea caracteristicilor și comportamentului obiectelor ce țin nemijlocit de domeniul problemei. Rezumatul este un model. În urma abstractizării, entităților din domeniul problemei se definesc prin clase.
Încapsularea – numită și ascunderea de informații, este caracterizată prin două aspecte:
Gruparea comportamentelor și caracteristicilor într-un tip abstract de date
Definirea nivelului de acces la datele unui obiect
Moștenirea – organizează și facilitează polimorfismul și încapsularea premițând definrea și crearea unor clase specializate plecând de la clase (generale) care sunt deja definite – acestea pot împărtăși (și extinde) comportamentul lor făra a fi nevoie de redefinirea aceluiași comportament.
Polimorfismul – posibilitatea mai multor obiecte dintr-o ierarhie de clase de a utiliza denumiri de metode cu același nume dar, cu un comportament diferit.
1.3.2. Moștenirea
Pentru tipurile de date obiectuale class este posibilă o operație de extindere sau specializare a comportamentului unei clase existente prin definirea unei clase noi ce moștenește datele și metodele clasei de bază, cu această ocazie putând fi redefiniți unii membri existenți sau adăugați unii membri noi. Operațiunea mai poartă numele de derivare.
Clasa din care se moștenește se mai numește clasă de bază sau superclasă. Clasa care moștenește se numește subclasă, clasă derivată sau clasă descendentă.
Ca și în Java, în C# o subclasă poate moșteni de la o singură superclasă, aducă avem de-a face cu moștenirea simplă; aceeași superclasă însă poate fi derivată în mai multe subclase distincte. O subclasă, la randul ei, poate fi superclasă pentru o altă clasă derivată. O clasă de bază împreună cu toate clasele descendente (direct sau indirect) formează o ierarhie de clase. În C#, toate clasele moștenesc de la clasa de baza Object.
În contextul mecanismelor de moștenire trebuie amintiți modificatorii abstract și sealed aplicați unei clase, modificatori ce obligă la și respectiv se opun procesului de derivare. Astfel, o clasă abstractă trebuie obligatoriu derivată, deoarece direct din ea nu se pot obține obiecte prin operația de instanțiere, în timp ce o clasă sigilată (sealed) nu mai poate fi derivată (e un fel de terminal în ierarhia claselor).
O metodă abstractă este o metodă pentru care nu este definită o implementare, aceasta urmând a fi realizată în clasele derivate din clasa curentă care trebuie să fie și ea abtractă (virtuală pură, conform terminologiei din C++).
O metodă sigilată este o metodă care nu mai poate fi redefinită în clasele derivate din clasa curentă.
1.3.3. Polimorfism
Polimorfismul este capacitatea unei entități de a lua mai multe forme, să se afle în diferite stări, și să aiba comportamente diferite. Polimorfisumul obectual, care trebuie să fie abstract, se manifestă în lucrul cu obiecte din clase aparținând unei ierarhii de clase, unde, prin redefinirea unor date sau metode, se obține membri diferiți având însă același nume.
Pentru a permite acest mecanism, metodele care necesită o decizie contextuală (în memontul apelului), se declară ca metode virtuale (cu modificatorul virtual). În mod curent, în C# modificatorul virtual al funcției din clasa de bază, îi corespunde un specificator override al funcției din clasa derivată ce redefinește funcția din clasa de bază.
O metodă ne-virtuală nu este polimorfică și, indiferent de clasa căreia îi aparține obiectul, va fi invocată metoda din clasa de bază.
În limbajul C# sunt admise trei tipuri de polimorfism:
Polimorfismul parametric este cea mai slabă formă de polimorfism, fiind regăsită în majoritatea limbajelor. Prin polimorfismul parametric se permite ca o implementare de funcție să poată prelucra orice număr de parametri. Acest lucru se poate obține prin folosirea în C# a unui parametru de tip params.
Polimorfismul ad-hoc se mai numește și spuraîncărcarea metodelor, mecanism prin care în cadrul unei clase se pot scrie mai multe metode, având acelați nume, dar tipuri și numere diferite de parametri de aple. Alegerea funcției care va fi apelată se va face la complilare, pe baza corespondenței între tipurile parametrilor de aple și tipurile parametrilor formali.
Polimorfismul de moștenire este forma cea mai evoluată de ploimorfism. Dacă precedentele forme de polimorfims sunt aplicabile fară a se pune problema de moștenire, în acest caz este necesar să existe o ierarhie de clase. Mecanismul se bazează pe faptul că o clasă de bază definește un tip care este compatibil din punct de vedere al atribuirii cu orice tip derivat, ca mai jos:
Figura 1.4. Exemplu de conversie implicită către baza B
1.4. ADO.NET
1.4.1. Arhitectura ADO.NET
ADO.NET (ActiveX Data Objects) reprezintă o parte componentă a nucleului .NET Framework ce permite conectarea la surse de date diverse, extragerea, manipularea și actualizarea datelor.
De obicei, sursa de date este o bază de date, dar ar putea de asemenea să fie un fișier text, o foaie Excel, un fișier Access sau un fișier XML.
În aplicațiile tradiționale cu baze de date, clienții stabilesc o conexiune cu baza de date și mențin această conexiune deschisă până la închiderea executării aplicației.
Conexiunile deschise necesită alocarea de resurse sistem. Atunci când menținem mai multe conexiuni deschise server-ul de baze de date va răspunde mai lent la comnezile clienților întrucât cele mai multe baze de date permit un număr foarte mic de conexiuni concurente.
ADO.NET permite și lucrul în stil conectat dar și lucrul în stil deconectat, aplicațiile conectându-se la server-ul de baze de date numai pentru extragerea și actualizarea datelor. Acest lucru permite reducerea numărului de conexiuni deschise simultatn la sursele de date.
ADO.NET oferă instrumentele de utilizare și reprezentare XML pentru transferul datelor între aplicații și surse de date, furnizând o reprezentare comună a datelor, ceea ce permite accesarea datelor din diferite surse de diferite tipuri și prelucrarea lor ca entități, fără să fie necesar să convertim explicit datele în format XML sau invers.
Aceste caracteristici sunt determinate în stabilirea beneficiilor furnizate de ADO.NET:
Interporabilitate. ADO.NET poate interacționa ușor cu orice componentă care suportă XML.
Durabilitate. ADO.NET permite dezvoltarea arhitecturii unei aplicații datorită modului de transfer a datelor între nivelele arhitecturale.
Programabilitate. ADO.NET simplifică programarea pentru diferite task-uri cum ar fi comenzile SQL, ceea ce duce la o creștere a productivității și la o scăderea numărului de erori.
Performanță. Nu mai este necesară conversia explicită a datelor la transferul între aplicații, fapt care duce la creșterea performanțelor acestora.
Accesibilitate. Utilizarea arhitecturii deconectate permite accesul simultan la același set de date. Reducerea numărului de conexiuni deschise simultan determină utilizarea optimă a resurselor.
Componentele principale ale ADO.NET sunt DataSet și Data Provider. Ele au fost proiectate pentru accesarea și manipularea datelor.
Figura 1.5. Arhitectura ADO.NET
1.4.2. Furnizori de date în ADO.NET
Din cauza existenței mai multor tipuri de surse de date este necesar ca pentru fiecare tip de protocol de comunicare să se folosească o bibliotecă specializată de clase.
Toate aceste clase implementează niște interfețe bine stabilite, ca atare trecereade la un SGBD la altul se face cu eforturi minore (dacă codul este scris ținând cont de prinicipiile programării orientate pe obiecte).
Tabelul 1.1. Furnizori de date.
Prefixele trecute în coloana ”Prefix” sunt folosite pentru clasele de lucru specifice unui anumit furnizor ADO.NET: de exemplu, pentru o conexiune SQL Server se va folosi SqlConnection.
Furnizorul de date permite unei aplicații să se conecteze la sursa de date, execută comenzi și salvează rezultate. Fiecare furnizor de date cuprinde componentele Connection, Command, DataReade și DataAdapter.
1.4.3. Connection
Înainte de orice operație cu o sursă de date externă, trebuie realizată o conexiune (legătură) cu acea sursă. Clasele din categoria Connection (SqlConnection, OleDbConnection etc.) conțin date referitoare la sursa de date (locația, numele și parola contului de acces, etc.), metode pentru deschiderea/închiderea conexiunii, pornirea unei tranzacții etc. Aceste clase se găsesc în subspații (SqlClient, OleDb etc.) ale spațiului System.Data. În plus, ele implementează interfata IdbConnection.
Pentru deschiderea unei conexiuni prin program se poate instanția un obiect de tip conexiune, precizându-i ca parametru un șir de caractere conținând date despre conexiune ca in exemplul următor:
Figura 1.6. Realizarea unei cinexiuni Sql
ConnectionString (String cu accesori de tip get și set ) definește un șir care permite identificarea tipului și sursei de date la care se face conectarea și eventual contul și parola de acces. Conțien lista de parametri necesari conectării sub forma parametru=valoare, separați prin;
Tabelul 1.2. Lista parametrilor necesari unei conexiuni.
ConnectionTimeout (int, cu accesor de tip get): specifică numărul de secunde pentru care un obiect de conexiune poate să aștepte pentru realizarea conectării la server înainte de a se genera o excepție (implicit 15). Se poate specifica o valoare diferită de 15 în ConnectionString folosind parametrul Connect Timeout, Caloarea Timeout=0 specifică asteptare nelimitată.
Figura 1.7. Realizarea unei cinexiuni Sql cu specificare de timp.
Database (string, read-only): returnează numele bazei de date care s-a făcut conectarea. Este necesară pentru a arăta unui utilizator care este baza de date pe care se face operarea.
Provider (de tip string, read-only): returnează furnizorul de date.
Serverversion (string, read-only): returnează versiunea de server la care s-a făcut conectarea.
State (enumerare de componente ConnectionState, read-only): returnează starea curentă conexiunii. Valorile posibile: Broken, Closed, Connecting, Fetching, Open.
1.4.3.(1) Metode
Open(): deschide o conexiune la baza de date.
Close(), Dispose(): închid conexiunea și eliberaează toate resursele alocate pentru ea.
BeginTransaction(): pentru executarea unei tranzacții pe baza de date; la sfârșit se apelează Commit() sau Rollback().
ChangeDatabase(): se modifică baza de date la care se vor face conexiunile. Noua bază de date trebuie să existe pe același server ca precedenta.
CreateCommand(): creează un obiect de tip Command valid (care implementează interfata IdbCommand) asociat cu conexiunea curentă.
1.4.3.(2) Evenimente
StateChange: apare atunci când se schimbă starea conexiunii. Handlerul corespunzător ( de tipul delegat stateChangeEventHandler) spune între ce stări s-a făcut tranziția.
InfoMessage: apare când furnizorul trimite un avertisment sau un mesaj către client.
1.4.4. Command
Clasele din categoria Command (SqlCommand, OleDbCommand etc.) conțin date referitoare la o comandă SQL (SELECT, INSERT, DELETE, UPDATE) și metode pentru executarea unei comenzi sau a unor proceduri stocate. Aceste clase implementează interfata IdbCommand. Ca urmare a interogării unei baze de date se obțin obiecte din categoriile DataReader sau DataSet. O comandă se poate executa numai după ce s-a stabilit o conexiune cu baza de date corespunzătoare.
Obiectele de tip SqlCommand pot fi utilizate într-un scenariu ce presupune deconectarea de la sursa de date dar și în operații elementare care presupun obșinerea unor rezultate imediate.
Proprietăți
CommandText (String): conține comanda SQL sau numele procedurii stocate care se execută pe sursa de date.
CommandTimeout (int): reprezintă numărul de secunde care trebuie să fie așteptat pentru executarea comenzii. Dacaă se depășeste acest timp, atunci se generază o excepție.
CommandType (enumerare de componente de tip CommandType): reprezintă tipul de comandă care se execută pe sursa de date. Valorile pot fi: StoredProcedure (apel de procedură stocată), Text (comandă SQL obișnuită), tableDirect (numai pentru OleDb).
Connection (System.Data.[Provider].PrefixConnection): conține obiectul de tip conexiune folosit pentru legarea la sursa de date.
Parameters (System.Data.[Provider].ParameterCollection): returnează o colecție de parametri care s-au transmis comenzii.
Transaction (System.Data.[Provider].PrefixTransaction): permite accesul la obiectul de tip tranzacție care se cere a fi executat pe sursa de date.
1.4.5. DataReader
DataReader permite explorarea datelor în modul conectat (cu ajutorul unor obiecte din categoria DataReader), sau pot fi preluate de la sursă (dintr-un obiect din categoria DataAdapter) și înglobate în aplicația curentă (sub forma unui obiect din categoria DataSet).
Clasele DataReader perit parcurgerea într-un singur sens a sursei de date, făra posibilitatea de modificare a datelor la sursă. Dacă se dorește modificarea datelor la sursă, se va utiliza ansamblul DataAdapter + DataSet. Datorită faptului că citește doar înainte (forward-only) permite acestui tip de date să fie foarte rapid în citire. Overhead-ul asociat este foarte mic (overhead generat cu inspectarea rezultatului și a scrierii în baza de date).
Dacă într-o aplicație este nevoie doar de informații care vor fi citite o singură dată , sau rezultatul unei interogări este prea mare ca să fie reținut în memoria (caching) DataReader este soluția cea mai bună.
Un obiect DataReader nu are constructor, ci se obține cu ajutorul unui obiect de tip Command și prin apelul metodei ExecuteReader(). Evident, pe toată durata lucului cu un obiect de tip DataReader, conexiunea trebuie să fie activă. Toate clasele DataReader (SqldataReader, OleDbDataReader etc.) implementează interfața IDataReader.
1.4.5.(1). Proprietăți
IsClosed (boolean, read-only): returnează true dacă obiectul este deschis și false altfel.
HasRows (boolean, read-only): verifică dacă reader-ul conține cl puțin o înregistrare.
Item (indexator de câmpuri).
FieldCount: returnează numărul de câmpuri din înregistrarea curentă.
1.4.5.(2). Metode
Close(): închide obiectul și eliberează resursele; trebuie să preceadă închiderea conexiunii.
GetBoolean(), GetByte(), GetChar(), GetDateTime(), GetDecimal(), GetDouble(), GetFloat(), GetInt16(), GetInt32(), GetInt64(), GetValue(), GetString(): returnează valoarea unui câmp specificat, din înregistrarea curentă.
GetBytes(), GetChars(): citirea unor octeți/caractere dintr-un câmp de date binar.
GetDataTypeName(), GetName(): returnează tipul/numele câmpului specificat.
IsDBNull(): returnează true dacă în câmpul specificat prin index este o valoare NULL
NextResult(): determină trecerea la următorul rezultat stocat în obiect.
Read(): determină trecerea la următorea înregistrare, returnând false numai dacă aceasta nu există.
DataReader obține datele într-un stream secvențial. Pentru a citi aceste informații trebuie apelată metoda Read; aceasta citește un singur rând din tabelul rezultat. Metoda clasică de a citi inforamția dintr-un DataReader este de a itera intr-o buclă while.
1.4.6. DataAdapter
La fel ca și Connection, Command, DataReader, obiectele de tip DataAdapter fac parte din furnizorul de date .NET specific fiecărui tip de sursă de date. Scopul clasei este să permită umplerea unui obiect DataSet cu date și reflectarea schimbărilor efectuate asupra acestuia înapoi în baza de date (DataSet permite lucrul deconectat de la baza de date).
Flosirea combinată a obiectelor DataAdapter și DataSet permit operații de selectare, ștergere, modificare și adăugare la baza de date. Clasele DataAdapter generează obiecte care funcționează ca o interfață între sursa de date și obiectele DataSet interne aplicației, permițând prelucrări pe baza de date. Ele gestionează automat conexiunea cu baza de date astfel încât conexiunea să se facă numai atunci când este necesar.
Un obiect DataSet este de fapt un set de tabele relaționale. Folosește serviciile unui obiect DataAdapter pentru a-și procura datele și trimite modificările înapoi către baza de date. Datele sunt stocate de un DataSet în format XML, același folosit și pentru transferul datelor.
Proprietăți
DeleteCommand, InserCommand, SelectCommand, UpdateCommand(Command), conțin comenzile ce se execută pentru selectarea sau modificarea datelor în sursa de date.
MissingSchemaAction (enumerare), determină ce se face atunci când datele aduse nu se potrivesc peste schema tabelei în care sunt depuse. Poate avea următoarele valori:
Add –implicit, DataAdapter adaugă coloana la chema tabelei.
AddWithKey – se adaugă coloana și informații relativ la cheia primară.
Ignore – se ignoră lipsa coloanei respective, ceea ce duce la pierderea de date.
Error – se generează o excepție de tipul InvalidOperationException.
Metode
Constructori de la cei impliciți până la cei în care se specifică o comandă de tip SELECT și conexiunea la sursa de date. Pentru un obiect de tip SqldataAdapter se poate crea o instanță în următorele moduri:
sau
Fill() – metodă polimorfică, permițând umplerea unei tabele dintr-un obiect de tip DataSet cu date. Permite specificarea obiectului DataSet, numărul de înregistrări cu care să se înceapă popularea (prima având inicele 0) și numărul de înregistrări care au fost aduse din bază. În clipa în care se apelează Fill() se procedează astfel:
Se deschide conexiunea (dacă ea nu a fost explicit deschisă).
Se aduc datele și se populeazp un obiect de tip DataTble din DataSet.
Se închide conexiunea (dacă ea nu a fost explicit deschisă).
Un DataAdapter își poate deschide și închide singur conexiunea, dar dacă aceasta a fost deschisă înaintea metodei Fill() atunci tot programul trebuie să se închidă.
Update() – metodă polimorfică, permitând reflectarea modificărilor efectuate între-un DataSet. Pentru a funcționa are nevoie de obiecte de tip comandă adecvate: proprietățile InsertCommand, DeleteCommand și UpdateCommand trebuie să indice către comenzi valide. Returnează de fiecare dată numărul de înregistrări afectate.
1.5. Tehnologii SMTP (Simple Mail Transfer Protocol)
1.5.1. Ce este SMTP?
Simple Mail Transfer Protocol (prescurtat, SMTP; în traducere aproximatvă Protocolul simplu de transfer al corespondenței) este parte a stratului de aplicare a protocolului TCP/IP. Folosind un proces numit ”stocare și redirecționare”, SMTP mută adresa dvs. de email pe și în rețele. Aceasta lucrează în strânsă colaborare cu Agentul de transfer de Mail (MTA) pentru a trimite comunicarea la emil-ul și calculatorul corect.
SMTP precizează și direcționează cum email-ul de pe MTA-ul calculatorului dumneavoastră se muta pe MTA-ul altui calculator, sau chiar pe mai multe calculatoare.
Folosind facilitatea mentionată anterior ”stocare și redirecționare”, mesajul se poate deplasa în mai muți pați de la calculator la destinație. La fiecare pas Simple Mail Transfer Protocol își va face treaba, toti acești pași realizându-se în spatele SMTP-ului.
SMTP este un protocol simplu, folosit pentru transmiterea mesajelor în format electronic pe internet. SMTP folosește portul de aplicație 25 TCP și determină adresa unui server SMTP pe baza înregistrării MX (Mail eXchange, ”schimb de corespondență”) din configurația serverului DNS.
Protocolul SMTP specifică modul în care mesajele de poștă electronică sunt transferate între procese SMTP aflate pe sisteme diferite. Procesul SMTP care are de transmis un mesaj este numit client SMTP iar procesul SMTP care primește mesajul este Serverul SMTP. Protocolul nu se referă la modul în care mesajul ce trebuie transmis este trecut de la utilizator către clientul SMTP, sau cum mesajul recepționat de serverul SMTP este livrat utilizatorului destinatar și nici cum este memorat mesajul sau de câte ori clientul SMTP încearcă să transmită mesajul.
1.5.2. Clasa MailAddress
Clasa MailAddress este utilizată de către clasele SmtpClient și MailMessage să stocheze informații adresă pentru mesajele de e-mail. O adesaă de e-mail este compusa dintr-un nume de utilizator, un nume gazdă și optțional un DisplayName. DisplayName poate conține caractere non-ASCII, dacă ele sunt codificate.
Clasa MailAddress acceptă următoarele formate de adese e-mail:
Un format adesă simplu user@host. Dacă un DisplayName este setat deja, acesta va fi formatul mail generat.
Un citat standard pentru afisare formatului de nume ”display name” <user@host>. Dacă un DisplayName este setat deja, acesta va fi formatul mail generat.
Parantezele unghiulare sunt adaugate în jurul numelui de utilizator si al numelui gazdă ”display name” user@hostâ dacă acestea nu sunt incluse.
Citatele sunt adăugate în jurul ”DisplayName” pentru display <name user@host> dacă acestea nu sunt incluse.
Caracterele Unicode sunt acceptate în DisplayName.
Un utilizator de nume cu citate. De exemplu ”user name”@host.
Puncte consecutive în numele de utilizator. De ecemplu user…name..@host.
Paranteze. De exemplu <user@[my domain]>.
1.5.3. Clasa SmtpClient
Clasa SmtpClient este folosită pentru a trimite e-mail la un server SMTP pentru livrare, protocolul SMTP fiind definit în RFC 2821.
Clasele prezentate în tabelul de mai jos sunt folosite pentru a construi mesaje e-mail care pot fi trimise folosind SmtpClient.
Tabelul 1.3. Clasele folosite pentru constuirea unui mesaj e-mail folosind SmtpClient..
Pentru a construi și a trimite un mesaj de e-mail cu ajutorul SmtpClient, trebuie să specificați următoarele informații:
Serverul gazda SMTP pe care îl utilizați pentru a trimite e-mail.
Acreditările pentru autentificare, dacă este necesar prin serverul SMTP.
Adresa de e-mail a expeditorului.
Adesa de e-mail sau adresele destinatarilor.
Conținutul mesajului.
Pentru a include o atașare cu un mesaj de e-mail, mai întâi creați atașarea utilizând clasa Attachment, și apoi adăugațil la mesaj folosind MailMessage.
Conexiunea stabilită de instanța curentă a clasei SmtpClient la serverul SMTP poate fi reutilizată daca se dorește trimiterea mai multor mesaje la același server SMTP. Acest lucru este deosebit de util atunci când autentificarea sau criptarea sunt folosite pentru a stabili o conexiune la serverul SMTP. Procesul de autentificare și de stabilire a unei sesiuni TLS poate fi o operațiune costisitoare. O cerință de a restabili o conexiune pentru fiecare mesaj atunci când se trimite un e-mail cu o cantitate mare la serverul SMTP ar putea avea un impact semnificativ asupra performanței.
Clasa SmtpClient nu conține metoda Finalize, așa că este necesară apelarea metodei Dispose pentru a elibera în mod explicit resursele. Metoda Dispose iterează prin toate conexiunile stabilite la serverul SMTP specificat în proprietatea gazdă și trimite un mesaj QUIT urmat de închiderea conexiuni TCP. Metoda Dispose eliberează, de asemenea, resursele negestionate utilizate de Socket și obțional dispune de resursele gestionate.
1.5.4. Clasa MailMessage
Clasa MailMessage permite, de asemenea, permite accesarea colectiei de antete pentru un mesaj folosit ca antet. În timp ce această colecției este read-only (o nouă colecție nu poate fi setată), antetele personalizate pot fi adăugate sau eliminate din această colecție. Orice antet personalizat și adaugat va fi inclus atunci când instanța MailMessage este trimisă. Înainte de a expedia un mesaj, doar anteturile adâugate special pentru această colecție vor fi incluse in colecție.
Dacă unele antete mail sunt malformate, acestea ar putea provoca mesajul e-mail să devină corupt. Deci orice antet mail în colecția de antete care poate fi setat cu ajutorul unei proprietăți din clasa MailMessage ar trebui stabilit numai cu ajutorul proprietății clasei MailMessage sau cu un paramteru atunci când MailMessage inizializează un obiect de tip MailMessage.
1.6. Algoritmi
1.6.1. Algoritmul Greedy
În limba engleză cuvântul ”greedy” înseamnă ”lacom”. Algoritmii de tip greedy vor sa construiască într-un mod cât mai rapid soluția unei probleme. Ei se caracterizează prin luarea unor decizii pe baza unui criteriu optim simplu și usor de verificat, care duc la găsirea unei soluții a problemei. Nu întotdeauna asemenea decizii verificabile ușor duc la o soluție optimă, de aceea trebuie să reușim identificarea acelor tipuri de probleme pentru care se pot obține soluții optime.
Algoritmii greedy se numara printre cei mai direcți algoritmi posibili. Ideea de bază este simplă: având o problemă de optimizare, de calculare a unui cost minim sau maxim, se va alege la fiecare pas deciziacea mai favorabilă, fără a evalua global eficiența soluției. În general există mai multe soluții posibile ale problemei. Dintre acestea se pot selecta doar anumite soluții optime, conform unor anumite criterii. Scopul este de a găsi una dintre acestea sau dacă nu este posibil, atunci o soluție cât mai apropriată, conform criteriului optimal impus.
Trebuie să întelegem că rezultatul obținut este optim doar dacă un optim local conduce la un optim global. În cazul în care deciziile de la un pas influențează lista de decizii de la pasul următor, este posibilă obținerea unei valori neoptimale. În astfel de cazuri, pentru găsirea unui optim absolut se ajunge și la soluții suprapolinomiale. De aceea, dacă se optează pentru o astfel de soluție, algoritmul trebuie însoțit de o demonstrație de corectitudine.
Descrierea formală a unui algoritm greedy este:
//
//
Este de înțeles acum de ce acest algoritm se numește lacom: la fiecare pas se alege cel mai bun candidat de la momentul respectiv, fără a studia situațiile viitoare. Procesul de construire al soluției este irevocabil: soluțiile parțiale ce nu pot fi optimizate sunt abandonate fără posibilitatea reevaluării la un pas anterior (x este eliminat din C chiar dacă nu va face parte din S final), iar dacă o subsoluție este greșită fezabilă la pasul curent atunci el va face parte cu siguranță din soluția finală.
Capitolul 2.
Fundamente- SQL Server
2.1. SQL Server
2.1.1. Scurtă introducere
O bază de date este o aplicație separată, care stochează o colecție de date. Fiecare bază de date are una sau mai multe API-uri distincte pentru crearea, accesarea, administrarea, căutarea și replicarea datelor pe care le dețin. În zilele noastre se folosesc sisteme de management al bazelor de date relaționale (RDBMS) pentru a stoca și manageria un volum imens de date. Aceasta se numește bază de date relațională, deoarece toate datele sunt stocate în diferite tabele și relațiile sunt stabilite folosind chei primare sau a altor chei cunoscute sub numele de chei externe. Un sistem de management de baze de date (RDBMS) este un software care:
permite să punem în aplicare o bază de date cu tabele, coloane, și indici,
garantează integritatea referențială între rânduri de diferite tabele,
actualizează indicii automat,
interpretează o interogare SQL și combină informațiile din diferite tabele.
Terminologia RDBMS
Înainte de a trece la explicarea sistemului de baze de date SQL Server, voi revizui câteva definiții legate de baze de date.
Bază de date: O bază de date este o colecție de tabele, cu date aferente.
Tabel: Un tabel este o matrice cu date. Un tabel într-o bază de date arată ca o foaie de calcul simplu.
Coloană: O coloană (element de date) conține date doar de un singur tip, de exemplu, coloana CodProdus.
Rând: Un rând (intrarea sau înregistrarea) este un grup de date întrudite.
Redutanță: Reprezintă stocarea în mod nejustificat a unei aceleași informații de mai multe ori în baza de date pentru a face sistemul mai rapid.
Cheie primară: Constrângerea cheie primară creează o cheie primară pentru tabel. Numai o singură cheie poate fi creată pentru fiecare tabel. Această constrângere este o coloană sau un set de coloane care identifică în mod unic fiecare rând al tebelului. Nicio coloană care face parte din cheia primară nu poate contine valoare nulă.
Cheie externă: O cheie externă este PIN-ul de legătură între două tabele. Această constrângere definește o coloană sau o combinație de coloane ca cheie externă și stabilește o relație între o cheie primară și una unică în același tabel sau în tabele diferite. O valoare care apare într-un tabel trebuie să se regăsească și în cel de-al doilea tabel, pe coloana unde se formează cheia primară. Constrângerile de tip cheie externă pot fi definite la nivel de coloană sau de tabel.
Cheie compusă: O cheie compusă (cheie compozit) este o cheie care constă din mai multe coloane.
Index: Un index într-o bază de date seamănă cu un indice de la partea din spate a unei cărți.
Integritate referențială: Integritatea referențială se asigură că o valoare cheie externă arată întotdeauna un rând existent.
SQL Server Database
Microsoft SQL Server este un sistem de gestionare de baze de date relaționale (RDBMS), produs de compania americană Microsoft. Microsoft SQL Server folosește o variantă SQL numit Transact SQL (T-SQL), care este o implementare de SQL-92 cu unele extensii pentru procedurile stocate și tranzacții.
SQL Server este un RDBMS rapid, ușor de utilizat, folosit atât pentru întreprinderile mici cât și pentru inteprinderi mai mari. SQL Server a devenit popular, din mai multe motive bune.
Microsoft pune la dispoziție varianta SQL Server Express care a fost lansată sub o licenta open-source.
SQL Server este un program foarte puternic. Se ocupă de un subset mare de funcționalități a pachetelor de baze de date mai scumpe și puternice.
SQL Server funcționează pe mai multe sisteme de operare și cu mai multe limbaje , inclusiv C+, Java C#, etc.
SQL Server acționează foarte rapid și funcționează bine și cu seturi mari de date.
2.1.2. Arhitectura client/server pe trei niveluri și avantajele acesteia
Figura 2.1. Arhitectura client/server pe trei niveluri.
Avantajele arhitecturii pe trei neveluir:
Separearea aplicației de cuncționalitatea bazei de date duce la o preluare a înărcăturii de date (load balancing) foarte eficientă;
Aplicarea unor reguli de securitate la nivel de server se poate face făra a se interveni în vreun fel la nivel de client;
În cazul aplicațiilor web, acest model oferă performanțe notabile, prin folosirea de obiecte persistente care consumă puține resurse (lightweight);
Flexibilitatea, atât în configurarea platformelor, cât și în implementarea (deployment) aplicațiilor Web;
Ușurința efectuării de update la orice nivel, făra a afecta funcționalitatea celorlalte;
Administrare eficientă.
Figura 2.2. Procesarea cererilor într-o arhitectură client/server pe trei niveluri.
2.1.3. Modelarea datelor
Proiectarea corectă a structurii unei baze de date relaționale este o premisă fundamentală în scrierea programelor de plicație și în funcționarea lor fără anomaliile care pot apărea în cazul unei structuri defectuase. Proiectarea stucturii bazelor de date relaționale este un domeniu în care cercetările au evoluat spre evoluare unor metodologii teoretice și a unor instrumente software care asigură un grad ridicat de normalizare a schemelor de relație, păstrarea integrității, evitarea anomaliilor datorate unei proiectări nesistematice.
Cateva dintre anomaliile care le-am putea întalni pe parcursul funcționării unei aplicație ar putea fi:
Reduntanța: reprezintă stocarea în mod nejustificat a unei aceleași informații de mai multe ori în baza de date.
Anomalia de stergere: spre exemplu la ștergerea din relație a ultimului produs al unui furnizor se pierd automat și datele despre acesta.
Anomalia de actualizare: în cazul actualizării unei informații redutante, se poate întampla ca operația să modifice unele apariții ale acesteia iar altele să ramană cu vechea valoare.
Anomalia de inserare: nu permite inserarea de date despre un furnizor decât dacă există în stoc un produs furnizat de acesta.
Impactul conceptelor de abstractizare și generalizare precum și elaborarea unui model de descriere informal a datelor, și anume modelul entitate-asociere (EA), au dus la găsirea unor căi algoritmizabile de proiectare optimă a bazelor de date. Modelul entitate-asociere este în acest moment cel mai populare model de comunicare a structurii bazelor de date datorită intuitivității și simplității elementelor sale.
Extensiile modelului EA au apărut și pentru alte necesități:
Modelarea cerințelor de secretizare a datelor,
Documentarea programelor de aplicație și ușurarea comunicării între proiectantul de sistem și utilizatorul obișnuit,
Proiectarea bazelor de date complexe pe porțiuni și integrarea ulterioară a acestora (așa numita integrare a vederilor).
Avantajul principal al modelului EA este acela al simplității sale și al caracterului său intuitiv. Rezultatul proiectării constă într-o diagramă entitate-asociere care poate fi apoi translatată în modelul de date folosit de sistemul de gestiune a bazelor de date ales pentru dezvoltarea aplicației.
Analiza de sistem
În acestă etapă se realizează analiza segmentului din lumea reală care va fi gestionat de aplicația respectivă. Rezultă o specificație neformalizată a cerințelor constând din două componente:
Cerințe privind conținutul bazei de date: categoriile de date care vor fi stocate și interdependențele dintre acestea.
Cerințe privind prelucrările efectuate de aplicație: prelucrările efectuate asupra datelor, arborele de meniuri al aplicației, machetele formatelor de introducere și prezentare a datelor și ale rapoartelor tipărite de aceasta.
În general această etapă nu poate fi asistată prin programe de tip CASE dar există reguli care ajută proiectantul în realizarea sa. Activitățile desfășurate includ:
Analiza activității desfășurate la momentul respectiv de beneficiarul aplicației sau de o mulțime reprezentativă de beneficiari în cazul aplicațiilor de uz general.
Analiza conținutului de date și a funcționalității aplicațiilor software – dacă există- care vor fi înlocuite de noua aplicație incluzând meniuri, machete ecran și machete de rapoarte.
Analiza formularelor tipizate și a altor documente utilizate de beneficiar pentru realizarea activității respective.
Identificarea tuturor interdependențelor dintre datele care vor fi stocate în baza de date și a restricțiilor privind valorile pe care le pot lua anumite categorii de date.
Identificarea – dacă este cazul – a prelucrărilor care se declanșează automat atât în cazul modificării bazei de date cât și la momente prestabilite de timp (de exemplu sfârșit de lună, de an, etc.).
Identificarea operațiilor care sunt necesare beneficiarului în activitatea curentă dar care în acest moment nu sunt realizate prin intermediul aplicațiilor software folosite precum și a operațiilor care pot fi incluse în mod natural în noua aplicație.
Identificarea bazelor de date existente care pot fi folosite de noua aplicație – direct sau printr-un import inițial de date – evitându-se în acest fel reintroducerea manuală a acestora.
Identificarea modalităților de transfer de date între noua aplicație și alte aplicații care rulează deja la beneficiar și care vor fi folosite și în viitor de către acesta.
Identificarea necesitățiilor privind datele și prelucrările care pot fi în viitor necesare beneficiarului, deci a posibilelor dezvoltări în timp ale aplicației.
Figura 2.3. Etapele poriectării unei aplicații.
Figura 2.3. prezintă schematic etapele proiectării unei noi aplicații care gestionează o bază de date, cu accentul pe partea de proiectare a structurii acesteia. Aceste etape fiind detaliate în paragrafele de mai sus.
Proiectarea conceptuală a bazei de date
În această etapă, pornind de la rezultatele analizei de sistem, se realizaeză modelarea cerințelor privind datele folosind un model de nievl înalt. Cel mai popular model folosit pentru aceasta este modelul entitate-asociere. Actualmente există pe piată numeroase instrumente CASE care folosesc diverse variante ale modelului. Motivele pentru care a fost ales sunt următoarele:
Nu este legat direct la nici unul dintre modelele folosite de sistemele de gestiune a bazelor de date (relațional sau orientat obiect) dar există algoritmi bine puși la punct de transformare din modelul EA în celelalte modele de date.
Este intuitiv, rezultatul modelării fiind o diagramă care definește atat datele stocate în baza de date cât și interdependențele dintre acestea.
Poate fi usor de înteles. Această caracteristică este foarte importantă în mementul în care se face punerea de acord cu beneficiarul asupra structurii bazei de date a aplicației, evitându-se în acest fel o proiectare neconformă cu realitatea sau cu cerințele exprimate de acesta.
Proiectarea se poate face pe porțiuni, diagramele parțiale rezultate putând fi apoi integrate pe baza unor algoritmi și metode bine puse la punct.
Transformarea în model relațional
În aceată etapă entitățile și asocierile care formează EA se transformă pe baza unor reguli clare în structura relațională a bazei de date . Rezultă schema preliminară a acesteia formată din tabele, coloanele acestora și constrângerile de integritate care pot fi deduse automat din diagramă incluzând unele interdependențe între date numite dependențe funcționale.
2.1.4. Normalizarea bazelor de date
Există câteva seturi de condiții care ne arată că o schemă de relație este corect proiectată în sensul că ea nu permite apariția anomaliilor prezentate la începutul capitolului. Dacă schema îndeplinește cerințele unui anumit set de condiții se spune că este în forma normală asociată acestui set.
În continuare sunt prezentate următoarele tipuri de forme normale.
Prima formă normală (1NF – First Normal Form). Prima formă normală este forma normală utilizată în normalizarea bazelor de date. Aceasă forma normală exclude posibilitatea existenței grupurilor repetitive cerând ca fiecare câmp într-o bază de date să cuprindă numai o valoare atomică. De asemenea, prima forma normală cere ca fiecare înregistrare să fie definită astfel încât să fie identificată în mod unic prin intermediul unei chei primare.
A doua formă normală (2NF – Second Normal Form). A doua formă normală cere ca toate elementele unei tabele să fie dependente funcțional de totalitatea cheii primare. Dacă unul sau mai multe elemente sunt dependente funcțional numai de o parte a cheii primare, atunci ele trebuie sa fie separate în tabele diferite. Dacă tabela are o cheie primară dormată din numai un atribut, atunci ea este automat în 2NF.
A treia formă normală (3NF – Third Normal Form). A treia formă normală cere ca toate atributele non-chei ale unei relații să depindă numai de chei candidate ale acelei relații. Bill Kent: ”the relation is based on the key, the whole key and nothing but the key”, la care unii adaugă: ”so help me Codd” (”relația depinde de cheie, de intreaga cheie si de nimic altceva decât de cheie”, la care unii adaugă ”asa să ne ajute Codd”). Toate atributele non-chei sunt (trebuie să fie) mutual independente.
Forma normală Boyce-Codd (BCNF – Boyce Codd Normal Form). Boyce-Codd e o versiune puțin mai restrictivă de forma normală 3. În cazul unei forme normale 3, toate atributele depind de o cheie, o cheie în întregime și numai de o cheie.
A patra forma normala (4NF – Fourth Normal Form). Cu toate că BCNF elimină toate anomaliile datorate dependențelor funcționale, mai există un tip de dependență , numită dependență multivalorică, ce poate cauza probleme de redutanță a datelor. A patra formă normală este o formă mai strictă dect BCNF pentru că împiedică relațiile să conțină dependențe multivalorice, prevenind astfel redutanța datelor. Normalizarea de la BCNF la 4NF presupune eliminarea dependențelor multivalorice prin plasarea atributului (atributelor) într-o nouă relație împreună cu o copie a determinantului.
Capitolul 3.
Aplicație: Dezvoltarea aplicativă
3.1. Descrierea aplicației
3.1.1. Motivul aplicației
Lucrarea de fată descrie cele mai des întalnite tehnici de definire și utilizare a bazelor de date precum și a documentelor Excel, însoțite de o exemplificare prin aplicatia Reinvestirea profitului unei firme in baza materiala realizată in C#. Aplicația de fată este un exemplu de ceea ce se poate realiza folisind tehnologiile respective.
Lucrarea este structurată în trei capitole, fiecare avand mai multe subcapitole, urmate de o serie de concluzii și listă cuprinzătoare de referințe bibliografice.
Tema lucrării intitulată „Reinvestirea profitului unei firme in baza materiala” extinde o suită de tehnologii Microsoft care au la bază Framework-ul .NET ce reprezintă un cadru de dezvoltare software unitară care permite realizarea, distribuirea și rularea aplicațiilor desktop Windows și aplicațiilor WEB.
Motivul alegerii acestei teme îl constituie posibilitatea care mi s-a dat în a lucra la un proiect care chiar are o finalitate practică dar și dorința de documentare și explorare a limbajului de programare C# precum și tehnologia programării orientată pe obiecte și a bazelor de date. Alături de profesorul coordonator care are pregătirea necesară și resursele necesare pentru ați permite să lucrezi și să extinzi un pachet software folosit de mii sau chiar sute de mii de oameni din întreaga lume, pot spune că am avut parte de o experiență fructuasă și tot suportul necesar pentru finalizarea proiectului.
Ca și aplicabilitate și exemplu de integrare a unei astfel de aplicații am folosit mediul de dezvoltare Visual Studio 2012, iar ca server de stocare a bazelor de date am ales sa folosesc SQL Server 2012. Structura lucrării este alcătuită din cinci ferestre principale (Logare, Cautare, Calculator, ExportDate și Ajutor), fiecare fereastră (form) dispue de o clasă proprie (StateLogare, StateCautare, StateCalculator, StateExportDate, StateAjutor) care extinde o clasă abstractă numită State.
Aplicația are la bază o matrice de tranziție care menegeriază acesul dintr-o fereastră în alta precum și o clasă abstractă State care conține mai multe metode abstracte care sunt implementate în fiecare clasă corespunzătoare ferestrei respective. Aplicația „Reinvestirea profitului unei firme în baza materială” oferă suport tehnic unei firme care dorește să investească în folosul angajațiilor o anumită sumă de bani în vederea modernizării birourilor, astfel furnizorul de echipamente trimite firemi o oferta avantajoasă cu produse în format Excel dupa cum urmează: cod_produs | denumire_firma | pret | cantitate | tip_produs. Aplicația verifică dacă toate birourile pot fi modernizate, iar în caz afirmativ va genera o soluție astfel încât suma ramasă să fie minimă. Dacă nu există o soluție se vor moderniza un număr maxim de birouri în ordinea priorității astfel încât suma ramasă să fie minimă.
Ca si obiective urmărite în realizarea algoritmului de calcul aș putea enumera următoarele:
Un birou poate fi modernizat numai complet;
Produsele mai scumpe vor fi cumpărate pentru birourile cu prioritate mai mare;
Aplicația se va folosi și anul următor – deci poate fi îmbunătațită cu cazuri noi;
Un birou primește un singur obiect din fiecare cod.
3.2. Paginile aplicației
3.2.1. Logarea în aplicație
Un utilizator care va urma să folosească aplicația trebuie să dețină un profil personal sau să iși creeze unul, format dintr-un nume de utilizator, parolă, nume, prenume și email, care vor fi introduse pe al doilea tab page intitulat Autentificare din pagina de logare (Figura (3.1)). Pentru creearea unui nou profil este necesară completarea tuturor câmpurilorcu, care au următoarea structură:
Nume utilizator – numele utilizatorului – pot fi introduse doar caractere alfa-numerice; câmp obligatoriu.
Parola – parola utilizatorului necesară logării în aplicație – pot fi introduse doar caractere alfa-numerice: câmp obligatoriu.
Nume – reprezintă numele utilizatorului necesar exportării datelor prin email – pot fi introduse doar caractere; câmp obligatoriu.
Prenume – prenumele utilizatorului care de asemenea este utilizat exportării datelor prin email; câmp obligatoriu.
Email – e-mailul utilizatorului care va reprezenta e-mailul de pe care se vor exporta datele; câmp obligatoriu.
Figura 3.1. Pagina de logare (Inregistrare).
Dupa completarea campurilor pentru înregistrare și crearea profilului, utilizatorul se poate loga. Pentru intrarea în aplicație este necesara completarea celor două câmpuri de pe tab page-ul Autentificare și selectarea unei obțiuni pe care dorim, aceasta fiind obligatorie pentru a ne putea loga în aplicație (Figura (3.2)).
Figura 3.2. Pagina de logare (Autentificare).
Dacă cele două intrări din câmpuri sunt înregistrate în baza de date ca fiind utilizator cu dreptul de a intra și a folosi aplicația, iar numele de utilizator și parola sunt corecte, Atunci se va deschide aplicația cu fereastra selectată din GroupBox-ul Opțiuni.
3.2.2. Căutarea și introducerea datelor
În această fereastră vom putea introduce datele necesare selectiei produselor de care utilizatorul are nevoie. Aferent acestei ferestre, va exista un buton în colțul stânga sus care va crea un OpenFileDialog care ne va permite sa cautam fișierul Excel care ne-a fost oferit de către furnizorul de produse în formatul: cod_produs | denumire_firma | pret | cantitate | tip_produs , aplicația preluând doar coloana ”tip_produs”, toate produsele fiind afisate intr-un DataGridView grupate, insoțite de o coloană tip boolean sub forma de checkbox-uri care va permite utilizatorului să selecteze produsele pe care le dorește(Figura(3.3)).
Figura 3.3. Pagina de căutare și introducere a datelor.
Înainte ca utilizatorul să înceapă sa selecteze produsele de care are nevoie este necesară introducerea numărului de birouri care se doresc a fi modernizate, precum și selectarea numărului de produse pe birou, care va influența numărul de produse care pot fi selectate în DataGridView.
Necompletarea celor două cămpuri ”Selectați numărul de birouri” și ”Selectați numărul de produse pe birou” nu va permite trecerea la pasul următor, aplicația geneând unul sau două mesaje de eroare informative în funcșie de campul necompletat, precum și un mesaj de eroare în cazul în care numărul de produse pe birou selectat nu coincide cu numărul de produse selectate în DataGridView.
Aferent GroupBox-ului existent pe această fereastră dacă se dorește trecerea la fereastra ”Calculator” aplicația va prelua toate produsele din fișierul Excel, carea au același ”tip_produs” cu cele selectate în DataGridView, ele fiind inserate în baza de date.
3.2.3. Fereastra Calculator
La afișarea acestei ferestre aplicația va popula noul DataGridView cu produsele ordonate din baza de date, și va insera două noi coloane ”Adaugat” și ”ID”, pe prima coloană vor fi completate numărul de produse in vederea achiziționării, a doua coloană reprezentând indicii după care aplicația va identifica produsele pe categorii. (Figura (3.4)).
Figura 3.4. Fereastra Calculator.
Pentru determinarea produselor care vor urma a fi achiziționate este necesar ca utilizatorul să introducă o sumă în câmpul ”Profit” în funcție de această sumă aplicația generând o soluție astfel încât suma rămasă să fie minimă. Pentru generearea solușiei sunt folosite o multitudine de funcții care au rolul de a verifica dacă toate birourile pot fi modernizate, în caz afirmativ se va genera o soluție astfel încât suma rămasă sa fie minimă. Dacă nu există o solușie se vor moderniza un număr maxim de birouri în ordinea proirității astfel încât suma rămasă să fie minimă.
3.2.4. Fereastra Export Date
Figura 3.5. Fereastra Export Date.
3.2.5. Fereastra Ajutor
Figura 3.6. Fereastra Ajutor.
Concluzii
Bibliografie
Anexe
Copyright Notice
© Licențiada.org respectă drepturile de proprietate intelectuală și așteaptă ca toți utilizatorii să facă același lucru. Dacă consideri că un conținut de pe site încalcă drepturile tale de autor, te rugăm să trimiți o notificare DMCA.
Acest articol: Reinvestirea Profitului Unei Firme In Baza Materiala (ID: 150365)
Dacă considerați că acest conținut vă încalcă drepturile de autor, vă rugăm să depuneți o cerere pe pagina noastră Copyright Takedown.
