Document, comentariu, eseu, bacalaureat, liceu si facultate
Top documenteAdmitereTesteUtileContact
      
    


 


Ultimele referate adaugate

Adauga referat - poti sa ne ajuti cu un referat?

Politica de confidentialitate



Ultimele referate descarcare de pe site
  CREDITUL IPOTECAR PENTRU INVESTITII IMOBILIARE (economie)
  Comertul cu amanuntul (economie)
  IDENTIFICAREA CRIMINALISTICA (drept)
  Mecanismul motor, Biela, organe mobile proiect (diverse)
  O scrisoare pierduta (romana)
  O scrisoare pierduta (romana)
  Ion DRUTA (romana)
  COMPORTAMENT PROSOCIAL-COMPORTAMENT ANTISOCIAL (psihologie)
  COMPORTAMENT PROSOCIAL-COMPORTAMENT ANTISOCIAL (psihologie)
  Starea civila (geografie)
 

Ultimele referate cautate in site
   domnisoara hus
   legume
    istoria unui galban
   metanol
   recapitulare
   profitul
   caract
   comentariu liric
   radiolocatia
   praslea cel voinic si merele da aur
 
despre:
 
Organizarea codului, programarea nestructurata, procedurala, modulara
Colt dreapta
Vizite: ? Nota: ? Ce reprezinta? Intrebari si raspunsuri
 
k5i17il
Ca urmare a cresterii complexitatii aplicatiilor software, in decursul dezvoltarii informaticii s-a impus o mai buna organizare a codului sursa, astfel incit acesta sa poata fi mai usor de inteles si de intretinut. Softul industrial trebuie intotdeauna extins si/sau modificat. Dezvoltarea rapida a unui nou produs program presupune reutilizarea codului existent. Aceste cerinte nu pot fi indeplinite practic fara a dispune de o buna organizare a codului.

In timp, au aparut mai multe propuneri de organizare a codului intr-un mod sistematic. Vom numi aceste moduri sistematice de organizare a codului sursa stiluri - vezi nota 1 - (sau paradigme) de programare. Distingem urmatoarele stiluri de programare (prezentate in ordinea crescatoare a gradului de organizare):

Programarea nestructurata

Programarea procedurala

Programarea modulara

Programarea cu tipuri abstracte de date

Programarea orientata pe obiecte

Daca un limbaj de programare permite scrierea de programe care sa respecte modul de organizare a codului specificat de catre un anumit stil, fara ca acest lucru sa implice utilizarea unor "trucuri" de programare, vom spune ca acel limbaj suporta stilul respectiv. Daca modul de organizare al codului specificat de catre un stil este respectat prin utilizarea unor "trucuri" de programare, vom spune ca limbajul permite utilizarea stilului respectiv. De exemplu, limbajul C nu suporta programarea cu tipuri abstracte de date sau programarea orientata pe obiecte, insa el permite (cu pretul scrierii unor programe mai dificil de inteles - contrar scopului adoptarii unui anumit stil) utilizarea acestor stiluri.

Programarea nestructurata
Dupa cum spune si numele, acest stil de proramare nu presupune nici o organizare a codului. Acest stil este folosit doar de catre programatorii incepatori (sau cei care isi insusesc un nou limbaj de programare). Toate datele si instructiunile se gasesc in acest caz in programul principal (eventual, pot exista variabile globale, desi acestea nu au nici un rol in acest context) intr-o singura unitate de compilare (un singur fisier sursa, din care, prin compilare, va rezulta un singur fisier obiect). Desi teoretic este posibil ca orice program sa poata fi scris utilizind acest stil, programele mari sunt dificil de inteles (si inca mai dificil de modificat). Daca aceeasi secventa de instructiuni trebuie aplicata in mai multe locuri din program, utilizind date de prelucrare diferite, secventa de instructiuni trebuie repetata in cod pentru fiecare prelucrare in parte. Aceasta duce la marirea nejustificata a programului. Reutilizarea codului este redusa doar la operatii de tip decupare/lipire (cut/paste) cu un editor. Evident, orice limbaj de programare suporta aceasta organizare.




Programarea procedurala
Programarea procedurala a fost din punct de vedere istoric primul stil de programare si continua probabil inca sa fie cel mai raspindit (desi comunitatea soft trece din ce in ce mai mult catre programarea orientata pe obiecte). In acest caz, codul este organizat conceptual pornind de la algoritmii utilizati in program. La nivelul limbajelor de programare, aceasta organizare conceptuala se concretizeaza prin codificarea algoritmilor in proceduri si functii. Limbajele de programare suporta acest stil daca ofera mecanisme pentru transmiterea de date de intrare (parametri) catre proceduri si preluarea de valori de la functii. Toate limbajele de programare actuale suporta acest stil de programare - vezi nota 2. Codul este mai bine organizat, facind posibila examinarea/intretinerea separata a procedurilor, care sunt portiuni identificabile de cod, cu o functionalitate bine precizata. Procedurile pot fi testate independent. Codul devine mai compact, iar reutilizarea se extinde la nivelul procedurilor. Eventual, acestea pot fi utilizate in programe diferite. Modificarea procedurilor nu afecteaza restul programului, atit timp cit modul de apelare a acestora ramine neschimbat. De exemplu, schimbarea algoritmului utilizat intr-o procedura de sortare, presupune doar rescrierea procedurii, fara a fi nevoie sa intervenim in alte parti ale programului.

Programarea modulara
Programarea modulara a aparut ca urmare a cumularii a mai multor tendinte in programare. Pe de o parte, programele au crescut in dimensiuni. Simpla organizare a codului in proceduri nu mai era suficienta. Au aparut astfel unitatile de compilare (numite in unele limbaje de programare module). Proceduri care indeplinesc sarcini asemanatoare (sau strins corelate) pot fi grupate in acelasi fisier, numit unitate de compilare. Programul poate fi impartit in mai multe fisiere constituite in unitati de compilare. Fiecare fisier poate fi compilat separat. Pe linga faptul ca procedurile pot fi localizate mai usor, reutilizarea codului se imbunatateste, fiind de aceasta data posibila reutilizarea codului compilat (fisierul obiect). Codurile obiect a mai multor unitati de compilare poate fi impachetat in biblioteci de programe.

Odata cu aparitia unitatilor de compilare, s-a pus problema identificarii de criterii bune pentru gruparea procedurilor. Deoarece reutilizarea cea mai eficienta este la nivel de cod compilat, un criteriu major de apreciere a calitatii unei impartiri in unitati de compilare il constituie minimizarea necesitatii de recompilare in cazul operarii unor modificari. In mod ideal, atunci cind o procedura trebuie modificata (fara insa a fi necesara modificarea modului de apel al procedurii), ar trebui recompilat doar fisierul care contine aceasta procedura. Deoarece fisierul care contine procedura de modificat trebuie oricum recompilat, se pot opera modificari in procedurile din acelasi fisier (fara a le modifica modul de apelare), acest fapt neconducind la cresterea costului compilarii. Prin urmare, este convenabil a grupa in acelasi fisier proceduri care se apreciaza ca vor trebui modificate impreuna in caz de necesitate. Practica programarii a demonstrat ca acest lucru poate fi realizat grupind in acelasi fisier proceduri care opereaza asupra unor date comune. Multe din schimbarile care trebuie realizate intr-un program se refera la schimbarea modului de reprezentare a unor date (aceasta schimbare poata fi impusa de exemplu de descoperirea unor algoritmi mai performanti care necesita un alt tip de reprezentare).

Cresterea dimensiunii programelor a impus ca acestea sa fie scrise de echipe tot mai numeroase de programatori, fiecare programator avind propriul sau stil de programare si propriile solutii de implementare. Inevitabil, fiecare programator utilizeaza o anumita structura de date facind anumite presupuneri asupra modului de utilizare a acelei structuri. Din pacate, presupunerile sale pot sa nu fie corelate cu cele ale unui alt programator care lucreaza la acelasi program. De exemplu, sa presupunem ca un programator implementeaza o structura de date care contine codul de judet format din doua litere (cel care apare pe numerele de inmatriculare ale autovehiculelor):

struct NrInmatriculare A

char codJudeta2i;

char *codLitere;

S nrInmatriculare;

Programatorul a facut presupunerea ca nimeni nu va utiliza cimpul codJudet in functii care manipuleaza siruri de caractere terminate prin caracterul nul (cod ASCII 0). Daca un alt programator va utiliza insa urmatoarea instructiune:

strcpy(nrInmatriculare.codJudet,"IS");

rezultatul va fi coruperea pointerului nrInmatriculare.codLitere, cu efecte potential dezastruoase asupra programului (coruperile de memorie fiind printre cele mai greu de depanat erori).

Exemplul de mai sus evidentiaza necesitatea ascunderii reprezentarii structurilor de date (data hiding), principiu care sta la baza implementarilor robuste. Conform acestui principiu, reprezentarea unei structuri de date trebuie sa nu fie accesibila decit procedurilor care in mod necesar trebuie sa lucreaze direct cu acea structura (de exemplu procedurile care creaza, modifica si distrug structura respectiva).

Principiul ascunderii datelor, in conjunctie cu modul ideal de structurare a programelor in unitati de compilare a dus la aparitia notiunii de modul program. Un modul program este un fisier sursa care contine date si proceduri destinate manipularii nemijlocite a acelor date. Structurile de reprezentare a datelor trebuie sa fie accesibile numai procedurilor care fac parte din acel modul. Procedurile trebuie sa ofere un set complet de operatii care pot fi realizate asupra structurilor de date. In acest mod se va asigura faptul ca vor fi realizate numai operatii permise asupra datelor. Organizarea programelor in programarea modulara se face in module. Desi acestea pot fi determinate de tipurile de date utilizate in program, acest lucru nu este in mod necesar preponderent.

Pentru a comunica intre ele, modulele definesc interfete. In cadrul interfetelor sunt declarate datele si procedurile care sunt accesibile din exteriorul modulului. Trebuie sa facem diferentierea intre unitati de compilare si module. O unitate de compilare este un fisier sursa. Un modul este o constructie sintactica a unui limbaj de programare care este capabila sa ascunda reprezentarea datelor si sa defineasca interfete. Este posibil ca o unitate de compilare sa contina mai multe module.

Limbajele Modula si Ada suporta in mod direct modulele. Nu exista o implementare directa a modulelor in C si nici in C++. Limbajul C doar permite utilizarea modulelor (prin intermediul unitatilor de compilare si a fisierelor antet). Limbajul C++ permite utilizarea modulelor (fiind o extensie a limbajului C) si ofera un mecanism superior de ascundere a datelor si definire a interfetelor prin intermediul claselor.

Vom exemplifica mai jos modul de implementare a modulelor in C in urmatorul exemplu. Fisierul inmatr.h va juca rolul interfetei unui modul care implementeaza structura de date (si operatiile asupra acestei structuri).

.

/* inmatr.h - defineste interfata inmatriculare */

char* citesteCodJudet();

void scrieCodJudet(char*);

Fisierul inmatr.c realizeaza implementarea interfetei:

/* inmatr.c - implementarea interfetei definite in inmatr.h */

struct NrInmatriculare A

char codJudeta2i;

char *codLitere;

S nrInmatriculare;

void scrieCodJudet(char* cod)

A

nrInmatriculare.codJudeta0i = coda0i;

nrInmatriculare.codJudeta1i = coda1i;

S

...

Celorlalti programatori li se va pune la dispozitie numai fisierul antet inmatr.h si codul obiect rezultat in urma compilarii fisierului inmatr.h, fara a avea acces la fisierul inmatr.c. Astfel, structura NrInmatriculare si variabila nrInmatriculare nu sunt cunoscute in exterior. Se previne astfel atit utilizarea eronata a acestei date, cit si necesitatea recompilarii altor fisiere in cazul modificarii structurii de date si/sau functiilor din fisierul inmatr.c:

/* main.c */

#include "inmatr.h" /* acces la interfata */

main()

A

scrieCodJudet("IS");

S

Cum este asigurata insa ascunderea reprezentarii daca este necesar sa se utilizeze in program mai multe variabile de tip NrInmatriculare? Aici intervine acel "truc de programare" despre care aminteam la inceputul acestui capitol. Fiecare variabila de tip NrInmatriculare va fi accesata prin intermediul unui pointer. Implementarea va trebui sa asigure crearea si distrugerea dinamica a unei structuri de tip NrInmatriculare. Prezentam mai jos modificarile care sunt necesare:

/* inmatr.h */

struct NrInmatriculare; /* Declara dar nu defineste

structura */

typedef struct NrInmatriculare* PNrInmatriculasre;

PNrInmatriculare creaza_nrInmatriculare(char*, char*);

distruge_nrInmatriculare(PNrInmatriculare);

char* citesteCodJudet(PNrInmatriculare);

void scrieCodJudet(PNrInmatriculare,char*);

...

/* main.c */

#include "inmatr.h"

main()

A

PNrInmatriculare nr1, nr2;

nr1 = creaza_nrInmatriculare("IS","ABCD");

nr2 = creaza_nrInmatriculare("","GHIJ");

scrieCodJudet(nr2,citesteCodJudet(nr1));

...

distruge_nrInmatriculare(nr1);

distruge_nrInmatriculare(nr2);

S

Implementarea este lasata ca exercitiu cititorului.

Programarea cu tipuri abstracte de date

Ascunderea reprezentarii in exemplul de mai sus este obtinuta prin sacrificarea simplitatii programului. In plus, programul nu lucreaza direct cu tipul de date, ci prin intermediul pointerilor. Acestia trebuie explicit creati si distrusi de catre programatori. Accesarea datelor este incetinita de nivelul suplimentar de indirectare. Ar fi convenabil sa existe un mecanism prin care tipurile de date definite de catre utilizatori sa fie tratate de catre compilator intr-un mod asemanator cu tipurile predefinite (int, char, float etc). Un astfel de mecanism este oferit de catre limbajele care suporta tipuri abstracte de date. Un tip abstract de date defineste semnificatia operatiilor care pot fi aplicate unei structuri de date. Nu vom prezenta aici modelul formal al tipurilor abstracte de date, un astfel de subiect fiind mai adecvat unui curs de Semantica limbajelor de programare. Retinem insa ca un tip abstract de date este o structura de date, plus multimea tuturor operatiilor fundamentale cu acea structura de date.

Tipurile abstracte de date inlocuiesc conceptul de ascundere a reprezentarii datelor cu cel de incapsulare a datelor. In incapsularea datelor, nu mai este esential ca structura datelor sa fie ascunsa, deoarece ea este protejata. Metafora capsulei este destul de reusita, in special daca ne imaginam capsula ca fiind transparenta (insa deosebit de rezistenta). Putem contrasta cele doua principii facind urmatoarea paralela: Putem transmite codul unui caracter de la tastatura unui calculator fara a face apel la tastatura, doar aplicind curenti avind diverse caractertistici in anumite contacte ale circuitelor calculatorului. Nimeni nu garanteaza insa ca ceea ce vom transmite va fi chiar caracterul dorit sau daca nu vom strica calculatorul. Pentru a impiedica ca acest lucru sa se intimple, principiul ascunderii reprezentarii datelor, transporta un calculator fara carcasa intr-o alta incapere. Incapsularea datelor ne lasa calculatorul pe birou, avind insa grija ca acesta sa dispuna de o carcasa (poate fi si transparenta) nedemontabila. Exista insa situatii (de exemplu atunci cind se doreste evitarea operatiilor de recompilare) in care incapsularea trebuie dublata de ascunderea reprezentarii datelor. In programarea orientata pe obiecte, incapsularea poate fi utilizata pentru a ascunde reprezentarea datelor -vezi nota 3.

Cel mai cunoscut limbaj care suporta tipuri abstracte de date (insa nu suporta programarea orientata pe obiecte) este Ada. Toate limbajele de programare orientate pe obiecte suporta tipurile abstracte de date. Vom exemplifica utilizarea tipurilor abstracte de date in C++:

// inmatr.h

class NrInmatriculare A

protected:

char codJudeta2i;

char* codNumeric;

public:

NrInmatriculare(char*, char*); // constructor

char citesteNrInmatriculare();

void scrieNrInmatriculare(char*);

...

S;

Desi reprezentarea tipului NrInmatriculare nu mai este ascunsa, ea nu este accesibila in exterior:

// main.c

#include "inmatr.h"

main()

A

NrInmatriculare nr1("IS","ABCD");

nr1.scrieNrInmatriculare("BC"); // corect

strcpy(nr1.codJudet,"BT"); // eroare compilare

...

S

In programarea cu tipuri abstracte de date, programul este organizat in functie de tipurile de date utilizate.

Neajunsurile programarii cu tipuri abstracte de date

Un tip de data abstract nu interactioneaza cu restul programului si nu poate fi adaptat la noi utilizari decit prin rescriere. Sa consideram drept exemplu o aplicatie grafica care deseneaza triunghiuri, cercuri si patrate:

enum TIP A triunghi, cerc, patrat S;

class Culoare A ... S;

class Punct A ... S;

class Figura A

protected:

TIP tip;

Culoare culoare;

Punct punct;....

public:

void deseneaza();

S;

void Figura::deseneaza()

A

switch(tip)

A

case cerc:

// deseneaza cerc

...

break;

case triunghi:

// deseneaza triunghi

...

break;

case patrat:

// deseneaza patrat

...

S

S

Functia deseneaza() trebuie sa stie totul despre afisarea fiecarui tip de figura. Aceasta functie va trebui modificata, de fiecare data cind programul este extins pentru a mai desena un tip de figura.

Programarea orientata pe obiecte
Problema de mai sus este cauzata de faptul ca in programarea cu tipuri abstracte de date nu se face o distinctie intre proprietatile comune tuturor figurilor (culoare, centru etc.) si proprietati si/sau proceduri specifice (precum desenarea). Un astfel de mecanism este asigurat in limbajele orientate pe obiecte prin derivarea de clase. In esenta, programarea orientata pe obiecte este programare cu tipuri abstracte de date, suplimentata cu un mecanism de derivare care specifica relatia generalizare/particularizare intre doua tipuri abstracte de date. In limbajele orientate pe obiecte, un tip abstract de date se numeste clasa. O clasa A este derivata dintr-o clasa B daca are toate caracteristicile clasei B (putind avea in plus caracteristici individuale).

In programarea orientata pe obiecte este posibil de a se realiza apeluri ale unor functii care nu sunt complet identificate in momentul compilarii:

class Forma A

protected:

Culoare culoare;

Punct centru;

...

public:

virtual void deseneaza();

...

S;

class Cerc : public Figura A

protected:

double raza;

...

public:

void draw();

...

S;

...

void deseneaza_toate_figurile(Figura* figuriai, int nrFiguri)

A

for(int i=0; i<nrFiguri; ++i)

figuriaii->deseneaza();

S

In momentul compilarii, nu se cunoaste care din functiile deseneaza va fi apelata pentru un indice i dat.

Organizarea programelor in programarea orientata pe obiecte se face in jurul obiectelor organiyate in clase -vezi nota 4. Programarea orientata pe obiecte asigura incapsularea asemenea cu programarea cu tipuri abstracte de date, oferind in plus o flexibilitate sporita si o mai buna reutilizare a codului, asigurate de mecanismul de derivare. Mai multe amanunte despre clase si derivarea de clase, in capitolele urmatoare.

Note:
In aceasta lucrare, prin stil intelegem exclusiv modul de organizare a codului in cadrul unui limbaj. Nu avem aici in vedere structura fundamentala a limbajului, structura care ne-ar indreptati sa vorbim despre programare procedurala (intr-un alt inteles decit cel de aici), programare logica sau programare functionala

Chiar daca unele limbaje de programare, precum limbajele de programare logica nu ofera explicit modalitati de exprimare a unei proceduri, se poate identifica un concept echivalent (definitia unui predicat).

Exista autori care nu fac distinctie intre incapsulare si ascunderea reprezentarii datelor, in principal datorita faptului ca incapsularea, dublata de posibilitatea de a defini clase abstracte (in programarea orientata pe obiecte) asigura pe deplin ascunderea reprezentarii datelor.
Exista limbaje de programare orientate pe obiecte in care obiectele nu sunt organiyate in clase ci prin intermediul prototipurilor.


Colt dreapta
Creeaza cont
Comentarii:

Nu ai gasit ce cautai? Crezi ca ceva ne lipseste? Lasa-ti comentariul si incercam sa te ajutam.
Esti satisfacut de calitarea acestui document, eseu, cometariu? Apreciem aprecierile voastre.

Nume (obligatoriu):

Email (obligatoriu, nu va fi publicat):

Site URL (optional):


Comentariile tale: (NO HTML)


Noteaza documentul:
In prezent fisierul este notat cu: ? (media unui numar de ? de note primite).

2345678910

 
Copyright© 2005 - 2024 | Trimite document | Harta site | Adauga in favorite
Colt dreapta