Metodologia abordării structurale a algoritmizării și programării. Programare structurală. Ce ne spune Floyd despre paradigme

Curs 1. Programare orientată pe obiecte.

Programarea orientată pe obiecte (OOP) este stilul dominant pentru crearea de programe mari. Principalele etape din evoluția abordării structurale în programare ajută la o mai bună înțelegere a relației abordare structurală, programare modularăși OOP.

Costul unitar al creării de programe s-a schimbat puțin până de curând. Odată cu creșterea volumului programului, costul unitar al creării acestuia ar putea crește neliniar. Timpul necesar pentru a crea programe complexe este proporțional cu pătratul sau chiar cubul cantității de programe. Prin urmare, unul dintre principalii factori care determină dezvoltarea tehnologiei de programare este reducerea costurilor de proiectare și creare a produselor software (SP) sau lupta împotriva complexității programării.

Alți factori care influențează evoluția metodelor de proiectare și construcție PCB sunt:

Schimbarea arhitecturii instalațiilor de calcul (CS) în interesul creșterii
performanță, fiabilitate;

Simplificarea interacțiunii utilizatorului cu aeronava și intelectualizarea aeronavei.
Acțiunea ultimilor doi factori este asociată cu o creștere a complexității software-ului aeronavei. Complexitate reprezintă o proprietate inerentă a programării şi a programelor care apareîn timpul și costul creării programelor, în volumul sau lungimea textului programului, în caracteristicile structurii sale logice, specificate de operatorii de transfer de control (ramificare, bucle, apeluri subrutine).

Există 5 surse de complexitate a programării:

Problema de rezolvat;

Limbaj de programare;

Mediul de execuție a programului;

Proces tehnologic de dezvoltare colectivă și creare de software;

Luptă pentru universalitatea și eficiența algoritmilor și a tipurilor de date.

Proprietatea complexității nu poate fi eliminată, dar caracteristicile manifestării acesteia pot fi modificate de management sau organizație.

Folosit pe scară largă în programare principiu fundamental controlul sistemelor complexe, care este cunoscut omului din cele mai vechi timpuri - divide et impera(divide and cuquer, lat.) și este utilizat în dezvoltarea și proiectarea oricăror sisteme tehnice complexe. Conform primei părți a acestui principiu, la proiectarea unui sistem software complex, descompunere algoritmică problema fiind rezolvata.

Scopul descompunerii este de a reprezenta sistemul în curs de dezvoltare sub forma unor subsisteme mici (module sau blocuri) care interacționează, fiecare dintre acestea putând fi depanare indiferent de ceilalți. Atunci când proiectați un sistem împărțit în subsisteme, este necesar să aveți în vedere informații despre un număr mult mai mic de detalii decât în ​​absența unei astfel de diviziuni.


Odată cu termenul descompunere , se foloseşte şi termenul structurarea probleme, sarcini sau programe. Ideile de împărțire a programelor în părți mari relativ independente care implementează anumite proceduri și funcții și formează o anumită ierarhie a relațiilor sunt reflectate în abordare structurală la dezvoltarea și crearea de software. În programare, abordarea structurală a apărut odată cu apariția primelor subrutine și funcții în care sunt scrise stil procedural. Acest stil se bazează pe regula: definiți variabilele și constantele care trebuie stocate în memoria computerului și descrieți algoritmul de procesare a acestora.

Formularea teoretică a abordării structurale a fost la începutul anilor '70 în lucrările teoreticienilor și practicienilor programării (A.P. Ershov, E. Yodan, N. Wirth). Trebuie remarcat apariția programării structurate, în care ideea de a ordona structura programului s-a reflectat într-o anumită măsură. Programare structurată se concentrează pe compilarea programelor a căror structură este apropiată de „arborele” operatorilor sau blocurilor. Utilizarea unei structuri de tip arbore ca un fel de standard se explică prin faptul că este o structură simplă pentru analiză și implementare.

Dezvoltarea în continuare a abordării structurale a condus la programare modulară. Acesta prevede descompunerea unei sarcini aplicate sub forma unei ierarhii de module sau programe care interacționează. Un modul care conține date și proceduri de procesare este convenabil pentru dezvoltarea și crearea offline. Specializarea modulelor pe tipuri de prelucrare și prezența unor date de anumite tipuri în ele sunt proprietăți care reflectă legătura dintre programarea modulară și OOP.

Cele mai importante instrumente ale producătorilor de PCB, care reflectă aproape toate aspectele evoluției, sunt limbaje de programare.

Limbajul de programare este axat inițial pe computer și conține un set de tipuri de date, operatori, operații, funcții care pot fi ușor traduse în comenzi pentru a controla hardware-ul și software-ul computerului. În același timp, este de dorit să se maximizeze eficiența traducerii propozițiilor de limbă în coduri de mașină în ceea ce privește minimizarea memoriei necesare, timpul de execuție a programului și costul creării unui traducător. În același timp, limbajul de programare este axat pe programator și oferă instrumente pentru modelarea obiectelor, proprietățile și comportamentul acestora la rezolvarea problemelor aplicate într-un anumit domeniu sub formă de programe.

Dezvoltarea limbilor în direcția creșterii eficienței compilarii programelor de aplicație a condus la împărțirea limbilor în următoarele niveluri:

Nivel scăzut (limbaje orientate către mașină - limbaje de asamblare),

Nivel înalt (limbi orientate către procedura: FORTRAN, ALGOL,

Nivelul sarcinii care se rezolvă (limbaje orientate către probleme - SQL).

Introducere tipuri de date a marcat o altă direcție în dezvoltarea tehnologiei
logica de programare. Tastarea datelor are scopul atât de a facilita
programare și să automatizeze detectarea erorilor folosind
date sub formă de operanzi și parametri reali la apelarea funcțiilor.
Utilizare tipuri de date structurale permite, în primul rând, simplificarea muncii algoritmistului la compararea structurilor de date ale sarcinii aplicate și a datelor prelucrate de funcțiile modulelor de program și, în al doilea rând, reducerea volumului de muncă de rutină a programatorului la codificarea algoritmului de procesare.

Rezultatul generalizării conceptului de „tip de date” sunt clase obiecte (C++), care pot conține ca elemente nu numai date de un anumit tip, ci și metode de prelucrare a acestora (funcții).

Astfel, odată cu dezvoltarea tehnologiei de programare, atât în ​​programe, cât și în tipuri de date, structura problemei aplicate în curs de rezolvare s-a reflectat din ce în ce mai adecvat și s-a realizat integrarea corespunzătoare a datelor și programelor în module. În același timp, limbajele de programare s-au completat mijloace necesar pentru descrieri structuri similare. Dezvoltarea ideilor de abstractizare și modularitate a dus la apariția în programare abordarea obiectului .

Omul gândește în imagini sau obiecte, le cunoaște proprietățile și le manipulează în conformitate cu anumite evenimente. Grecii antici au deținut ideea că lumea poate fi privită sub formă de obiecte și evenimente. Oamenii au de obicei orientat pe obiecte vedere asupra lumii. Deci, gândindu-ne la un telefon, o persoană își poate imagina nu numai forma și culoarea acestuia, ci și capacitatea de a efectua un apel, natura sunetului apelului și o serie de alte proprietăți (în funcție de cunoștințele sale tehnice, de imaginație) .

Limbajul de programare vă permite să descrieți proprietățile obiectelor simulate și ordinea manipulării cu obiecte sau ordinea interacțiunii acestora, în conformitate cu condițiile problemei care se rezolvă. Primele limbaje de programare s-au concentrat pe obiecte matematice, pe un anumit model de calculator. Prin urmare, ele conțineau astfel de construcții precum parametri variabili, constante, funcții, formali și actuali. Programatorii și-au reprezentat programele ca funcții și module care interacționează. Natura programării a fost orientată procedural, din moment ce s-a acordat prioritate secvențelor de acțiuni cu date. În consecință, sunt numite limbaje de programare precum FORTRAN, PL-1, C orientat procedural.

Datele și subrutinele au fost combinate în module în conformitate cu logica designerilor care creează sisteme software complexe pentru domenii specifice ale aplicației lor. Logica integrării în module a fost determinată de o serie de factori, printre care trebuie remarcat proprietățile domeniului: datele și subrutinele pentru prelucrarea lor, corespunzătoare unei anumite clase de obiecte din domeniul subiectului, au fost combinate într-un modul. Deci, modulul de procesare a șirurilor conținea funcții pentru efectuarea operațiilor de bază cu șiruri: concatenare, comparare, copiere, calculare a lungimii unui șir.

Dezvoltarea ideii de programare modulară este compararea obiectelor din domeniul subiectului (obiecte modelate) cu structuri software numite obiecte, tipuri de obiecte sau clase (modelarea obiectelor). Obiectele de modelare conțin date și funcții care descriu proprietățile obiectelor modelate. Deci, datele pot reflecta proprietăți indicative sau cantitative (masă, lungime, putere, preț), în timp ce funcțiile reflectă proprietăți comportamentale sau operaționale (schimbarea masei, calcularea puterii, stabilirea prețului). Astfel, odată cu abordarea obiectului, integrarea datelor și funcțiile prelucrării acestora este determinată de structura domeniului subiectului, adică de ansamblul obiectelor modelate, interacțiunea acestora în cadrul problemei care se rezolvă.

Un obiect modelat este întotdeauna prezentat unei persoane ca ceva unificat, integral, deși poate consta din părți sau alte obiecte. O reprezentare holistică a unui obiect sub forma unui set interconectat de proprietăți sau componente este principiu de bază abordarea obiectului.

Abordarea obiectului a început să se dezvolte în programare încă din anii 70 (Smalltalk, CLOS, Ada). Aceste limbi sunt numite obiectiv. Clasificarea ierarhică facilităţi şi moştenire proprietățile sunt ideile de plecare ale abordării orientate pe obiecte care au apărut în anii '80. Unul dintre motivele dezvoltării relativ lente a stilului de programare orientat pe obiecte este diferența semnificativă a acestuia față de stilul procedural.

Programare- o ramură relativ tânără și în dezvoltare rapidă a științei și tehnologiei. Experiența realizării unor dezvoltări reale și îmbunătățirii software-ului și hardware-ului existent este în mod constant regândită, în urma căreia apar noi metode, metodologii și tehnologii care, la rândul lor, servesc drept bază pentru instrumente de dezvoltare software mai moderne. Este recomandabil să se studieze procesele de creare a noilor tehnologii și să se determine principalele tendințe ale acestora prin compararea acestor tehnologii cu nivelul de dezvoltare al programării și cu caracteristicile software-ului și hardware-ului disponibil programatorilor.

tehnologie de programare numiți un set de metode și instrumente utilizate în procesul de dezvoltare software. Ca orice altă tehnologie, tehnologia de programare este un set de instrucțiuni tehnologice, inclusiv:

  • indicarea succesiunii operațiilor tehnologice;
  • enumerarea condițiilor în care se realizează cutare sau cutare operațiune;
  • descrieri ale operațiunilor în sine, unde pentru fiecare operațiune sunt definite datele inițiale, rezultatele, precum și instrucțiunile, reglementările, standardele, criteriile și metodele de evaluare etc.

Pe lângă setul de operații și succesiunea acestora, tehnologia determină și modalitatea de a descrie sistemul proiectat, sau mai degrabă modelul utilizat într-un anumit stadiu de dezvoltare.

Programare orientată pe obiecte (OOP) este definită ca o tehnologie pentru crearea unui software complex bazat pe reprezentarea unui program ca un set de obiecte, fiecare dintre acestea fiind o instanță de un anumit tip (clasă), iar clasele formează o ierarhie cu moștenirea proprietăților. Interacțiunea obiectelor software într-un astfel de sistem se realizează prin transmiterea de mesaje.

Principalul avantaj al programării orientate pe obiecte în comparație cu programarea modulară este descompunerea „mai naturală” a software-ului, care facilitează foarte mult dezvoltarea acestuia. Acest lucru duce la o localizare mai completă a datelor și integrarea acestora cu subprograme de procesare, ceea ce permite dezvoltarea aproape independentă a părților (obiectelor) individuale ale programului. În plus, abordarea obiect oferă noi modalități de organizare a programelor bazate pe mecanismele de moștenire, polimorfism, compoziție și conținut. Aceste mecanisme fac posibilă construirea de obiecte complexe din unele relativ simple. Ca urmare, rata de reutilizare a codului crește semnificativ și devine posibilă crearea de biblioteci de clase pentru diverse aplicații.



Dezvoltarea rapidă a tehnologiilor de programare bazate pe abordarea obiectului a făcut posibilă rezolvarea multor probleme. Așa au fost create mediile care suportă programarea vizuală, de exemplu, Delphi, C++ Builder, Visual C++ etc. Când folosește un mediu vizual, un programator are posibilitatea de a proiecta o parte, de exemplu, interfețele unui viitor produs, folosind instrumente vizuale pentru adăugarea și configurarea componentelor speciale ale bibliotecii. Rezultatul designului vizual este pregătirea unui program viitor, în care codurile corespunzătoare au fost deja introduse.

Se poate da o definiție generală: Obiect OOP este o colecție de variabile de stare și metode (operații) asociate. Aceste metode definesc modul în care un obiect interacționează cu mediul.

Sub metode obiect să înțeleagă proceduri și funcții a căror declarație este inclusă în declarația obiectului și care efectuează acțiuni. Capacitatea de a controla stările unui obiect prin apelarea unor metode determină în cele din urmă comportamentul unui obiect. Acest set de metode este adesea denumit interfața unui obiect.

Programarea structurată (SP) a apărut ca o soluție la problema reducerii COMPLEXITĂȚII dezvoltării software.

La începutul erei programării, munca unui programator nu era reglementată de nimic. Sarcinile de rezolvat nu diferă ca amploare și scară, s-au folosit în principal limbaje orientate pe mașină și limbi apropiate acestora, cum ar fi Assembly, programele dezvoltate rareori atingeau dimensiuni semnificative și nu existau restricții stricte de timp. a dezvoltării lor.

Pe măsură ce programarea s-a dezvoltat, au apărut sarcini pentru care s-au determinat intervale de timp limitate pentru sarcini din ce în ce mai complexe cu implicarea unor grupuri de programatori. Și, ca urmare, dezvoltatorii se confruntă cu faptul că metodele potrivite pentru dezvoltarea sarcinilor mici nu pot fi utilizate în dezvoltarea proiectelor mari din cauza complexității acestora din urmă.

Astfel, scopul programării structurate este de a crește fiabilitatea programelor, de a asigura întreținere și modificări, facilitând și accelerând dezvoltarea.

Metodologie de programare imperativă structurată - o abordare care constă în stabilirea unei bune topologii a programelor imperative, inclusiv respingerea utilizării datelor globale și a operatorului de salt necondiționat, dezvoltarea modulelor cu conectivitate puternică și asigurarea independenței acestora față de alte module.

Abordarea se bazează pe două principii principale:

· Descompunerea secvenţială a algoritmului de rezolvare a problemei de sus în jos.

Utilizarea codurilor structurale.

Reamintim că această metodologie este cea mai importantă dezvoltare a metodologiei imperative.

Origine, istorie și evoluție. Edsger Dijkstra este considerat a fi creatorul abordării structurale. De asemenea, deține o încercare (din păcate, complet inaplicabilă programării în masă) de a combina programarea structurată cu metode de demonstrare a corectitudinii programelor create. Oameni de știință atât de cunoscuți precum H. Mills, D.E. Knuth, S. Hoor.

Metode și concepte care stau la baza programării structurate. Se află trei

Metodă descompunere algoritmică de sus în jos- constă în detalierea pas cu pas a enunţului problemei, începând cu problema cea mai generală. Această metodă oferă o structură bună. Metoda este susținută de conceptul de algoritm.

Metodă organizarea modulară a părților programului- consta in despartirea programului in componente speciale numite module. Metoda este susținută de conceptul de modul.

Metodă codificare structurală- constă în utilizarea a trei structuri principale de control la codificare. Etichetele și operatorul de salt necondiționat sunt legături greu de urmărit de care vrem să ne lipsim. Metoda este susținută de conceptul de control

Limbaje structurale de programare. Principala diferență față de metodologia clasică a programării imperative constă în eșec (mai precis, acest sau acel grad de eșec) de la operatorul de sărituri necondiționate .

„O proprietate importantă a sintaxei pentru un programator este capacitatea de a reflectă în structura programului structura algoritmului de bază. Când utilizați o metodă cunoscută sub numele de programare structurată, programul este construit ierarhic - de sus în jos (de la programul principal la subprogramele de cel mai de jos nivel), folosind doar un set limitat de structuri de control la fiecare nivel: secvențe simple de instrucțiuni, bucle și unele tipuri de ramuri condiționate. Odată cu implementarea consecventă a acestei metode, structura algoritmilor rezultați este ușor de înțeles, de depanat și modificat. În mod ideal, ar trebui să putem traduce schema de program construită în acest fel direct în instrucțiunile de program corespunzătoare care reflectă structura algoritmului.

Teorema de structurare (Boem-Jacopini): Orice program corect (adică un program cu o intrare și o ieșire fără bucle și ramuri inaccesibile) poate fi scris folosind următoarele structuri logice - secvență, selecție și repetare buclă

Corolarul 1: Orice program poate fi redus la o formă fără o declarație goto.

Consecința 2: Orice algoritm poate fi implementat într-un limbaj bazat pe trei structuri de control - secvență, ciclu, repetiție.

Corolarul 3: Complexitatea programelor structurate este limitată, chiar dacă dimensiunea lor este nelimitată.

Programarea structurată nu este un scop în sine. Scopul său principal este de a obține un program bun („corect”), dar chiar și în cel mai bun program, uneori sunt necesare instrucțiuni goto: de exemplu, pentru a ieși din multe bucle imbricate.

Practic, în toate limbile care susțin metodologia imperativă, este posibil să se dezvolte programe folosind această metodologie. Un număr de limbi au introdus înlocuitori speciali pentru declarația goto pentru a facilita gestionarea buclelor (de exemplu, Break and Continue în C).

Clasa de sarcini. Clasa de probleme pentru această metodologie corespunde clasei de probleme pentru metodologia imperativă. Rețineți că în acest caz este posibil să se dezvolte programe mai complexe, deoarece sunt ușor de perceput și analizat.

programare structurata - acestea sunt anumite principii și reguli generale pentru proiectarea, dezvoltarea și execuția programelor pentru a facilita procesele de creare și testare a acestora, de a crește productivitatea programatorilor și de a îmbunătăți lizibilitatea programului rezultat. Structura programului și algoritmul de rezolvare a problemei ar trebui să fie ușor de înțeles, ușor de dovedit corect și ușor de modificat. În esență, abordarea structurală este respingerea unui stil dezordonat în algoritmizare și programare (în special, respingerea operatorului goto) și definirea unui număr limitat de tehnici standard pentru construirea de algoritmi și programe ușor de citit cu o structură clar definită, care este deosebit de importantă atunci când se dezvoltă sisteme software mari.

Experiența utilizării metodelor de programare structurală în dezvoltarea, de exemplu, a unui număr de sisteme de operare complexe arată că corectitudinea structurii logice a sistemului în acest caz este ușor de demonstrat, iar sistemul în sine permite testarea destul de completă. Reducerea problemelor de depanare și testare a programelor duce la o creștere a productivității programatorului, deoarece o treime până la jumătate din timpul de dezvoltare este cheltuit pentru testarea unui program. Productivitatea unui programator este de obicei măsurată prin numărul de instrucțiuni depanate pe care le poate scrie într-o zi. Estimările aproximative arată că utilizarea metodelor de programare structurată poate crește acest număr de 5-6 ori. De asemenea, trebuie spus că programarea structurată presupune o anumită organizare a procesului de programare în sine și o anumită tehnologie de proiectare a programelor, ceea ce afectează pozitiv și productivitatea programatorilor.

Fundamentele programării structurate. Fundamentul teoretic al programării structurate este teorema de structurare, din care rezultă că algoritmul (programul) de rezolvare a oricărei probleme practic calculabile poate fi reprezentat folosind trei structuri elementare de control de bază: structura secvenței (secvența); structuri de ramificare, structuri de ciclu prezentate în fig. 6.5-6.7, respectiv, unde P este o condiție, S este un operator.

Structura secvenței reprezintă fluxul natural al algoritmului – orice succesiune de instrucţiuni care se execută una după alta (vezi Fig. 6.5). Într-un limbaj de programare, aceasta corespunde unei secvențe de instrucțiuni de intrare, ieșire și atribuire.

Reprezintă un factor de decizie, include verificarea unei condiții logice P și, în funcție de rezultatele acestei verificări, executarea operatorului S1 sau a operatorului S2. În limbajele de programare (de exemplu, Pascal) este implementat de instrucțiunea if P apoi SI else S2 (vezi Fig. 6.6).

Structura buclei (buclă cu precondiție) reprezintă factorul de repetabilitate a calculului, asigură că execuția instrucțiunii S se repetă de mai multe ori în timp ce logica (adevărată)

Orez. 6.5.Structura secvenței

Orez. 6.6.

condiția P. În limbajele de programare (de exemplu, Pascal) este implementată de operator în timp ce P do S (vezi Fig. 6.7).

Setul de bază de structuri de control este complet funcțional, adică. cu ajutorul acestuia, puteți crea orice algoritm arbitrar complex, cu toate acestea, pentru a crea algoritmi și programe mai compacte și vizuale, sunt utilizate structuri de control suplimentare: structura de ramificare abreviată; structura opțiunii sau alegere multiplă; structură buclă cu un parametru; structură buclă cu postcondiție. În diferite limbaje de programare, implementarea structurilor de control de bază poate fi diferită, de exemplu, toate structurile propuse sunt implementate în limbajul Pascal.

Orice program poate fi construit prin intermediul unei compoziții de structuri de bază: fie prin conectarea lor în serie - formând structuri secvențiale, fie prin imbricarea lor unele în altele - formând structuri imbricate.

Fiecare dintre structuri poate fi considerată ca un bloc funcțional cu o intrare și o ieșire. Blocurile S, SI, S2, care fac parte din structurile de control de bază, pot fi ele însele unul dintre ele, deci sunt posibile construcții imbricate. Cu toate acestea, indiferent de gradul și adâncimea „cuibării”, este important ca orice design să aibă în cele din urmă o intrare și o ieșire. Prin urmare, orice structură complexă poate fi considerată o „cutie neagră” cu o intrare și o ieșire. Astfel, este posibil să introduceți transformarea oricărei structuri într-un bloc funcțional. Apoi, orice algoritm compus din structuri standard se pretează la o transformare secvențială într-un singur bloc funcțional, iar această secvență de transformări poate fi folosită ca mijloc de înțelegere a algoritmului și de demonstrare a corectitudinii acestuia. Secvența inversă a transformărilor poate fi utilizată în procesul de proiectare a unui algoritm cu dezvăluirea treptată a unui singur bloc funcțional într-o structură complexă de elemente de bază.

Pentru structurarea și înțelegerea programelor mari, se folosesc și instrumente structurale suplimentare care sprijină principiul modular al dezvoltării PS: acestea sunt subprograme și module. Utilizarea mașinii subrutine (proceduri și funcții) - aceasta este capacitatea de a separa secțiunile de cod separate (repetate frecvent) în unități de program independente cu propriile lor date de intrare și ieșire pentru apelul lor multiplu ulterioar din diferite puncte ale programului și din alte subrutine. Modul este o bibliotecă autonomă compilată de descrieri de tipuri, date, proceduri și funcții, care permite gruparea descrierilor datelor și subrutinelor în funcție de funcțiile și scopul acestora, conform unuia dintre principiile de bază ale programării structurate - împărțirea sarcinilor mari în subsarcini.

Metodologia de dezvoltare a programelor. Două metode (strategii) de dezvoltare a programelor legate de programarea structurată sunt comune: programarea de sus în jos; programare de jos în sus.

Programare de sus în jos sau proiectare de program de sus în jos, este o tehnică de dezvoltare a programelor în care dezvoltarea începe cu definirea obiectivelor de rezolvare a problemelor, urmată de detalierea secvențială, care se termină cu un program detaliat. În primul rând, sunt evidențiate câteva dintre cele mai globale sarcini, a căror soluție poate fi reprezentată în structura generală prin blocuri independente funcțional. Dezvoltarea structurii logice a fiecărui astfel de bloc și modificarea acestuia pot fi efectuate independent de celelalte blocuri. În această primă etapă a proiectului, sunt dezvăluite cele mai importante și esențiale legături, sunt determinate scopul funcțional al fiecărui bloc, datele sale de intrare și ieșire. În etapele de proiectare ulterioare, structura logică a blocurilor funcționale individuale ale circuitului general este rafinată (detaliată), care poate fi, de asemenea, realizată în mai multe etape de detaliere până la cele mai simple instrucțiuni. La fiecare etapă a proiectului se efectuează multiple verificări și corecții.

Această abordare este destul de rațională, poate accelera semnificativ procesul de dezvoltare a proiectelor software complexe și poate evita în mare măsură deciziile eronate. În plus, devine posibil să nu se implementeze imediat unele subrutine (module), ci să se amâne temporar dezvoltarea lor până la finalizarea altor părți. De exemplu, dacă este necesar să se calculeze o funcție matematică complexă, atunci este alocată o subrutină separată a unui astfel de calcul, aceasta este implementată temporar de un operator, care atribuie pur și simplu valoarea dorită. Când întreaga aplicație este scrisă și depanată, puteți începe să implementați această caracteristică complexă.

Programare proiectare software de jos în sus sau de jos în sus aceasta este o tehnică de dezvoltare a programelor care începe cu dezvoltarea subprogramelor (proceduri, funcții), în timp ce dezvoltarea schemei generale nu s-a încheiat. Această tehnică este mai puțin preferată decât designul de sus în jos, deoarece duce adesea la rezultate nedorite, rescrierea codului și creșterea timpului de dezvoltare. Utilizarea acestuia poate fi adecvată atunci când un nou proiect utilizează soluții proprietare bine-cunoscute.

Principii generale pentru dezvoltarea proiectelor software. Utilizarea tehnologiei de programare structurată în dezvoltarea proiectelor software serioase se bazează pe următoarele principii:

  • programarea trebuie efectuată „de sus în jos”;
  • întregul proiect ar trebui împărțit în module/subrutine cu o intrare și o ieșire;
  • orice subrutină ar trebui să permită doar trei structuri de bază: execuția secvențială a instrucțiunilor, ramificare și buclă;
  • transferul necondiționat al operatorului de control goto nu este permis;
  • documentația ar trebui creată în același timp cu programarea, parțial sub formă de comentarii de program. Aplicarea principiilor și metodelor de programare structurată face posibilă creșterea fiabilității programelor (datorită unei bune structurări în timpul proiectării, programul poate fi ușor testat și depanat) și eficiența acestora (structurarea programului face ușor de găsit și corectat). erorile, iar subprogramele individuale pot fi refăcute / modificate independent de altele), reduc timpul și costul dezvoltării software, îmbunătățesc lizibilitatea programelor.

Programarea este procesul de compilare a programelor (traducerea unui algoritm într-un limbaj de programare).

Un program este o secvență completă de instrucțiuni ale limbajului de programare care definește procedura de rezolvare a unei probleme specifice de prelucrare a datelor.

În zilele noastre, „limbajul de programare” și „limbajul algoritmic” sunt adesea folosite ca sinonime.

La compilarea algoritmilor complecși, se folosește o abordare, care se numește structurală. Componentele principale ale acestei abordări:

Design de sus în jos pas cu pas;

Programare structurata;

Programare modulară;

Control structural de la capăt la capăt.

Programarea structurală presupune compilarea unui algoritm de problemă din construcții de tip strict definit.

Orice algoritm poate fi reprezentat printr-o combinație de structuri algoritmice de bază de trei tipuri: liniară, ramificată și ciclică.

Fiecare structură trebuie să aibă o intrare și o ieșire. La fiecare pas de proiectare de sus în jos, trebuie compilat un algoritm de unul dintre cele trei tipuri indicate (Fig. 7.2).

Dezvoltarea de sus în jos vă permite să controlați mai bine cursul (procesul) de programare.

Un program scris folosind structuri de control devine mai clar, mai fiabil și mai ușor de întreținut. Principiile modularității cresc dramatic versatilitatea unui produs software.

Controlul structural este necesar pentru a detecta și corecta erorile cât mai curând posibil, în timp ce costul corectării erorilor este minim, iar consecințele acestora sunt cele mai puțin semnificative.

A). Linear: b). Ramificare: c). Ramificare din

ramura degenerata:

Cu precondiție: - cu postcondiție: - cu un număr cunoscut de repetări:

Orez. 7.2. Tipuri de structuri de control

Limbaje de programare

În programare, se disting limbaje de diferite niveluri: mașină, asamblare, nivel înalt (limbaje algoritmice).

Limbajul mașină este un sistem de instrucțiuni pentru un anumit computer, care este implementat direct de acesta. Structura unui program de mașină nu este fixă, deoarece variabilele și constantele pot fi intercalate cu instrucțiuni în orice ordine. Controlul asupra utilizării corecte a zonelor de memorie este efectuat numai de programator. Acest lucru duce la un număr mare de erori, care uneori sunt foarte greu de detectat.

Dezavantajele programării în limbajul mașinii:

Costuri mari de muncă la înregistrarea unui program;

Complexitatea procesului de depanare a programelor;

Dificultate în atingerea unor indicatori înalți de fiabilitate a programului, productivitatea programatorilor;

Limbajul este asociat cu un anumit tip de computer.

Avantaje:

Programe de înaltă eficiență;

Posibilitatea de a utiliza toate resursele hardware ale computerului.

Limbajele la nivel de asamblare sunt orientate către mașină. Assembler vă permite să compuneți programe într-o formă mai prietenoasă cu oamenii.

Avantajele asamblatorului:

Adresarea simbolică;

Abilitatea de a conecta mai multe programe într-un singur modul;

Disponibilitatea instrumentelor de control al erorilor;

Eficiență suficient de mare a programelor;

Utilizarea tuturor capabilităților computerului.

Defecte:

Detalierea excesivă a programelor de înregistrare;

Lipsa controlului asupra accesului la elementele de memorie.

Limbile de nivel înalt nu conțin declarații dependente de mașină. Limbi de acest tip: Fortran, Algol, BASIC, Focal, Pl/1, Pascal, Cobol etc.

Avantajele programării în aceste limbaje:

Productivitate ridicată a programatorilor;

Ușurința în utilizare a programelor;

Abilitatea de a transfera programe de la o mașină la alta (adică universalitate).

Defecte:

Eficiență redusă a programelor în comparație cu limbajele de nivel scăzut;

Utilizarea nu întotdeauna optimă și completă a resurselor informatice;

Necesitatea unei memorie de computer de a avea un program special de traducător scris în limbajul mașinii (sau asamblator), care prelucrează descrierea simbolică a algoritmului și traduce automat programul în limbajul intern al mașinii.

Există două tipuri principale de traducători: compilatori și interpreți. Un compilator este un program care convertește întregul program sursă într-un limbaj de mașină dintr-o singură mișcare. Programul rezultat se numește program obiect (modul). Este modulul obiect care este apelat de sistemul de operare pentru execuția ulterioară (calculele) a programului.

Un interpret este un program care traduce fiecare instrucțiune a programului sursă și o execută imediat.

Am pregătit acest articol în timpul discuțiilor despre modelul Bridge, dar nu l-am publicat atunci. Am crezut că și-au dat seama, din moment ce s-a menționat Domain Driven Design și se părea că nevoia de proiectare și programare în stil OOP nu a fost contestată de nimeni. Dar totuși, cu timpul, m-am lovit de o neînțelegere. Acesta va fi un articol pur teoretic istoric. Desigur, chiar și fără a încerca să acopere întreaga lățime a subiectului. Dar acesta este, ca să spunem așa, un mesaj către un tânăr dezvoltator care citește partea de sus și nu poate alege ce principii și reguli să urmeze, ce este primar și ce este secundar.

Titlul acestui subiect pentru mulți acum poate părea foarte controversat (și destul de intenționat provocator, dar pentru afaceri :)). Dar totuși, vom încerca să argumentăm acest lucru aici și să înțelegem ce proprietăți ar trebui să aibă o paradigmă de programare pentru a avea dreptul de a fi numită paradigmă.

Vă întreb doar dacă îl citiți în diagonală - comentați cu reținere.

Ce ne spune Floyd despre paradigme?

Termenul „paradigma de programare” a fost inventat de Robert Floyd („R. W. Floyd.” „Communications of the ACM”, 22(8):455-460, 1979. douăzeci de ani (1966-1985), M.: MIR, 1993. ). În prelegerea sa din 1979, el spune următoarele:

Un exemplu familiar de paradigmă de programare este programarea structurată, care pare a fi paradigma dominantă în metodologia de programare. Este împărțit în două faze. În prima fază, proiectarea de sus în jos, problema este împărțită într-un număr mic de sub-probleme mai simple. Această descompunere ierarhică treptată continuă până când apar sub-probleme distincte care sunt suficient de simple pentru a fi tratate direct. A doua fază a paradigmei de programare structurată implică lucrul în sus de la obiecte și funcții concrete la obiecte și funcții mai abstracte utilizate în modulele produse prin design de sus în jos. Dar paradigma de programare structurată nu este universală. Chiar și cei mai înflăcărați apărători ai săi ar recunoaște că ea singură nu este suficientă pentru a ușura toate problemele grele. Alte paradigme de nivel înalt de tip mai specializat continuă să fie importante. (Aceasta nu este o traducere exactă, ci o compilație a autorului bazată pe prelegerea lui R. Floyd, dar aderând la cuvintele sale cât mai mult posibil. Formularea a fost schimbată și aranjată doar pentru a evidenția ideea principală a lui R. Floyd și pentru a înțelege prezentarea acestuia.)

El continuă menționând programarea dinamică și programarea logică, numindu-le și paradigme. Dar particularitatea lor este că au fost dezvoltate dintr-un domeniu specializat, au fost găsiți niște algoritmi de succes și au fost construite sisteme software corespunzătoare. El continuă spunând că limbajele de programare ar trebui să sprijine paradigmele de programare. Și, în același timp, indică faptul că paradigma de programare structurată este o paradigmă de nivel superior:

Paradigma """chiar""" a unui nivel superior de abstractizare decât paradigma """programare structurată"" este construirea unei ierarhii de limbaje, în care programele în limbajul de cel mai înalt nivel acționează asupra obiectelor abstracte și traduc le în programe în limbajul următor nivel inferior.

Caracteristici ale paradigmelor de nivel superior

După cum putem vedea, R. Floyd a distins și paradigmele în paradigme de nivel superior și mai specializate. Ce caracteristici ale paradigmelor ne permit să spunem că sunt de nivel superior? Desigur, aceasta este posibilitatea aplicării lor la diferite sarcini de subiect. Dar ce face paradigmele aplicabile problemelor diferitelor subiecte? Desigur, întrebarea aici nu este în specificul problemei obiective, care poate fi rezolvată printr-o abordare sau alta. Toate paradigmele care propun să creeze algoritmi într-un mod sau altul specializat nu sunt deloc paradigme, sunt doar o abordare specială în cadrul unei paradigme de nivel superior.

Și există doar două paradigme de nivel înalt: programarea structurată și o programare de nivel și mai înalt, orientată pe obiecte. Mai mult, aceste două paradigme la nivel înalt se contrazic, iar la nivel scăzut, nivelul de construire a algoritmilor, ele coincid. Și deja abordări (paradigma de nivel scăzut), cum ar fi logic, dinamic, funcțional, pot fi bine folosite în cadrul paradigmei de programare structurală și sunt folosite unele specializări care au apărut - aspect, agent-oriented, event-oriented. în cadrul paradigmei de programare orientată pe obiecte. Astfel, acest lucru nu înseamnă că programatorii trebuie să cunoască doar una sau două paradigme de nivel înalt, dar cunoașterea altor abordări va fi utilă atunci când rezolvă o problemă mai specializată, de nivel scăzut. Dar, în același timp, atunci când trebuie să proiectați software, trebuie să începeți cu paradigme de nivel superior și să treceți la cele de nivel inferior, după cum este necesar. Dar dacă există o problemă de alegere a principiilor cărora să se acorde preferință, principiile paradigmelor de nivel inferior nu ar trebui niciodată să prevaleze asupra principiilor paradigmelor de nivel superior. Deci, de exemplu, principiile programării structurate nu trebuie urmate în detrimentul principiilor programării orientate pe obiecte, iar principiile programării funcționale sau logice nu ar trebui să încalce principiile programării structurate. Singura excepție este viteza algoritmilor, care este problema optimizării codului de către compilatori. Dar din moment ce nu este întotdeauna posibil să se construiască compilatoare perfecte, iar interpretarea paradigmelor de nivel superior este, desigur, mai complicată decât a celor de nivel scăzut, uneori trebuie să trecem la nerespectarea principiilor paradigmelor de nivel înalt. .

Dar să revenim la întrebarea noastră: ce face paradigmele aplicabile la diferite probleme de subiect? Dar pentru a răspunde, trebuie să facem o digresiune istorică.

Fundamentele paradigmei de programare structurată

Știm că ideile despre programarea structurată au apărut după raportul lui E. Dijkstra din 1965, unde a fundamentat respingerea operatorului GOTO. Acest operator a fost cel care a transformat programele în nestructurate (cod Spaghetti), iar Dijkstra a demonstrat că este posibil să se scrie programe fără a utiliza acest operator, ceea ce a dus la structurarea programelor.

Dar teoria este una, iar practica este alta. În acest sens, este interesant să luăm în considerare care era situația până în 1975. Acest lucru se vede clar în cartea lui E. Yodan (). Este important să luăm în considerare acest lucru deoarece acum, la peste 30 de ani mai târziu, principiile deja bine cunoscute atunci sunt acum redescoperite și ridicate la un nou rang. Dar, în același timp, se pierde contextul istoric, și ierarhia importanței acestor principii, ce este primar și ce este secundar. Această situație de amorf caracterizează foarte bine starea actuală a programării.

Dar ce sa întâmplat atunci? După cum descrie Yodan, totul începe cu răspunsul la întrebarea „Ce înseamnă să scrii un program bun?”. Iată primul criteriu la care ar trebui să răspundă o paradigmă de programare de nivel înalt. Dacă nu răspunde direct la această întrebare, dar vă spune cum puteți obține unele caracteristici interesante ale programului dvs., atunci aveți de-a face cu o abordare de paradigmă de nivel scăzut atunci când programați.

În zorii programării, a existat o astfel de abordare a evaluării programatorilor prin viteza de scriere a programelor. Înseamnă asta că scrie programe bune? Se bucură de dispoziția și respectul deosebit al conducerii? Dacă răspunsul la ultima întrebare este da, atunci toate întrebările de îmbunătățire a programării sunt mai mult de interes academic. Dar conducerea poate observa, de asemenea, că unii superprogramatori pot realiza programe foarte rapid sau pot scrie programe foarte eficiente, dar aceste programe rămân uneori neformatate, imposibil de înțeles, întreținut sau modificat. Și acesta din urmă necesită, de asemenea, mult timp.

De remarcat este o dispută destul de tipică între programatori:
* Programator A: „Programul meu este de zece ori mai rapid decât al tău și ocupă de trei ori mai puțină memorie!”
* Programator B: „Da, dar programul tău nu funcționează, dar al meu merge!”

Dar programele devin tot mai complexe și, prin urmare, nu este suficient pentru noi ca programul să funcționeze. Sunt necesare anumite metode pentru a verifica funcționarea corectă a programului și a programatorului însuși. Mai mult, aceasta nu este testarea programului, ci realizarea unei proceduri sistematice de verificare a corectitudinii programului în sensul organizării sale interne. Adică, chiar și atunci, în termeni moderni, s-a vorbit despre revizuirea codului (Code review).

În plus, deja atunci au vorbit despre flexibilitatea programului - despre simplitatea schimbării, extinderii și modificării acestuia. Pentru a face acest lucru, trebuie să răspundeți constant la întrebări de un anumit tip. „Ce se întâmplă dacă dorim să extindem acest tabel?”, „Ce se întâmplă dacă într-o zi vrem să definim un nou program de modificare?”, „Ce se întâmplă dacă trebuie să schimbăm formatul unor astfel de date de ieșire?”, „Ce se întâmplă dacă cineva decide să introducă date în program într-un mod diferit?”.

S-a vorbit și despre importanța specificațiilor interfeței, adică. o abordare formalizată a specificației intrărilor, funcțiilor și ieșirilor care urmează să fie implementate de fiecare modul.

În plus, s-a acordat o atenție centrală dimensiunii și imuabilității modulului. În plus, în ceea ce privește imuabilitatea modulului, acesta nu a fost luat în considerare în întregime, ci cu alocarea factorilor individuali:
1. Structura logică a programului, i.e. algoritm. Dacă întregul program depinde de o abordare specială, câte module vor trebui modificate când algoritmul se schimbă?
2. Argumente, sau parametri, ai modulului. Acestea. modificarea specificației interfeței.
3. Variabile și constante de tabel interne. Multe module depind de tabele partajate, dacă structura unor astfel de tabele se modifică, ne putem aștepta ca și modulele să se schimbe.
4. Structura și formatul bazei de date. Într-o măsură mai mare, această dependență este similară cu dependența de variabilele și tabelele partajate menționate mai sus, cu diferența că, din punct de vedere practic, este mai convenabil să considerăm baza de date ca fiind independentă de program.
5. Structura modulară de management al programului. Unii oameni scriu un modul fără să se gândească cu adevărat la modul în care va fi folosit. Dar dacă cerințele s-au schimbat. Ce parte din structura logică a modulului va trebui să schimbăm?

Acestea și multe alte aspecte (pe care nu le-am luat în considerare aici) formulează în general ideea de programare structurată. Îngrijirea acestor aspecte este ceea ce face din programarea structurată o paradigmă de nivel înalt.

Fundamentele paradigmei de programare orientată pe obiecte

După cum am văzut, toate principiile organizării unor programe bune sunt acoperite în programarea structurată. Apariția altuia sau a unui grup de principii până acum necunoscute ale scrierii unui software bun ar putea schimba paradigma? Nu. Ar extinde doar modalitățile și ideologia de a scrie programe structurate, de exemplu. paradigma de programare structurată.

Dar dacă paradigmele de nivel înalt sunt concepute pentru a răspunde la întrebarea cum să scrie un program bun, iar apariția unei noi tehnici tehnice, sau luarea în considerare a unor noi factori, nu permite depășirea limitelor programării structurale (deoarece va rămâne structurale, indiferent de numărul de tehnici și factori), atunci ceea ce va permite apoi să depășim granițele acestei paradigme. Într-adevăr, așa cum se știe din știință în general, paradigmele nu se schimbă atât de repede. Revoluțiile științifice au loc rar, când paradigma anterioară, deja în practică, din concepțiile teoretice existente, pur și simplu nu poate explica fenomenele care au loc. Avem o situație similară la schimbarea paradigmei de la structurală la orientată pe obiect.

Este deja recunoscut că motivul apariției paradigmei orientate pe obiect a fost nevoia de a scrie programe din ce în ce mai complexe, în timp ce paradigma de programare structurată are o anumită limită, după care devine insuportabil de dificil să se dezvolte un program. Iată, de exemplu, ceea ce scrie G. Schildt:

În fiecare etapă a dezvoltării programării, metodele și instrumentele au părut să „frâneze” complexitatea tot mai mare a programelor. Și la fiecare astfel de etapă, noua abordare a absorbit tot ce e mai bun din cele anterioare, marcând progresul în programare. Același lucru se poate spune despre OOP. Înainte de OOP, multe proiecte au atins (și uneori au depășit) limita dincolo de care o abordare structurată a programării nu mai funcționa. Prin urmare, pentru a depăși dificultățile asociate cu complicarea programelor, a fost nevoie de OOP. ()

Pentru a înțelege motivul pentru care programarea orientată pe obiecte a făcut posibilă scrierea unor programe mai complexe și practic să înlăture problema apariției unei limite de complexitate, să ne întoarcem la unul dintre fondatorii OOP - Grady Booch (). El își începe explicația despre OOP cu ce înseamnă complexitatea și ce sisteme pot fi considerate complexe. Adică abordează intenționat problema scrierii de programe complexe. Apoi trece la întrebarea relației dintre complexitate și capacitatea umană de a înțelege această complexitate:

Există o altă problemă principală: limitările fizice ale capacităților umane atunci când lucrați cu sisteme complexe. Când începem să analizăm un sistem software complex, există multe părți componente care interacționează între ele în diferite moduri și nici părțile sistemului în sine, nici felul în care interacționează, nu prezintă nicio asemănare. Acesta este un exemplu de complexitate neorganizată. Când începem să organizăm un sistem în procesul de proiectare, este necesar să ne gândim la multe lucruri deodată. Din păcate, o singură persoană nu poate urmări toate acestea în același timp. Experimentele psihologilor precum Miller arată că numărul maxim de unități structurale de informații pe care creierul uman le poate urmări simultan este de aproximativ șapte plus sau minus doi. Astfel, ne confruntăm cu o dilemă serioasă. """Complexitatea sistemelor software este în creștere, dar capacitatea creierului nostru de a face față acestei complexități este limitată. Cum putem ieși din această problemă?"""

Apoi vorbește despre descompunere:

Descompunere: algoritmică sau orientată pe obiecte? Care descompunere a unui sistem complex este mai corectă - prin algoritmi sau pe obiecte? Există o captură la această întrebare, iar răspunsul corect la aceasta este că ambele aspecte sunt importante. Separarea algoritmică se concentrează pe ordinea evenimentelor care au loc, în timp ce separarea obiectelor subliniază agenții care sunt fie obiecte, fie subiecte ale unei acțiuni. Cu toate acestea, nu putem construi un sistem complex în două moduri în același timp. Trebuie să începem prin a împărți sistemul fie pe algoritmi, fie pe obiecte, iar apoi, folosind structura rezultată, să încercăm să luăm în considerare problema dintr-un alt punct de vedere. Experiența arată că este mai util să începeți cu descompunerea obiectelor. Acest început ne va ajuta să ne ocupăm mai bine de organizarea complexității sistemelor software.

Astfel, el preferă și principiile orientate pe obiect în detrimentul principiilor structurale, dar subliniază importanța ambelor. Cu alte cuvinte, principiile structurale trebuie să se supună principiilor orientate pe obiect pentru ca creierul uman să facă față complexității sarcinilor care apar. El continuă subliniind importanța modelului:

Importanța construirii unui model. Modelarea este omniprezentă în toate disciplinele de inginerie, în mare parte pentru că implementează principiile de descompunere, abstractizare și ierarhie. Fiecare model descrie o anumită parte a sistemului luat în considerare, iar noi, la rândul nostru, construim noi modele pe baza celor vechi, în care suntem mai mult sau mai puțin încrezători. Modelele ne permit să ne controlăm eșecurile. Evaluăm comportamentul fiecărui model în situații normale și neobișnuite și apoi facem ajustările corespunzătoare dacă ceva nu ne mulțumește. Cel mai util este să creați modele care să concentreze atenția asupra obiectelor găsite în domeniul însuși și să formeze ceea ce am numit descompunere orientată pe obiecte.

Acum, dacă te uiți mai atent, se dovedește că paradigma orientată pe obiecte nu este altceva decât modelare în general, aspectul căruia cel mai important a fost cel mai clar exprimat de S. Lem:

Modelarea este o imitație a Naturii, ținând cont de câteva dintre proprietățile sale. De ce doar câteva? Din cauza incapacității noastre? Nu. În primul rând, pentru că trebuie să ne protejăm de supraîncărcarea informațională. Un astfel de exces, însă, poate însemna și inaccesibilitatea lui. Artistul pictează, dar deși am putea vorbi cu el, nu știm cum își creează lucrările. Despre ce se întâmplă în creierul lui când pictează un tablou, el însuși nu știe. Informații despre asta sunt în capul lui, dar nu ne sunt disponibile. Modelarea ar trebui simplificată: o mașină care poate picta un tablou foarte modest ne-ar spune mai multe despre fundamentele materiale, adică cerebrale, ale picturii decât un „model” atât de perfect al artistului, care este fratele său geamăn. Practica modelării implică luarea în considerare a unor variabile și respingerea altora. Modelul și originalul ar fi identice dacă procesele care au loc în ele ar coincide. Acest lucru nu se întâmplă. Rezultatele dezvoltării modelului diferă de dezvoltarea efectivă. Trei factori pot influența această diferență: simplificarea modelului în comparație cu originalul, proprietățile modelului care sunt străine de original și, în sfârșit, incertitudinea originalului în sine. (fragment din lucrarea „Suma tehnologiilor”, Stanislav Lem, 1967)

Astfel, S. Lem vorbește despre abstracție ca bază a modelării. În același timp, abstracția este principala caracteristică a paradigmei orientate pe obiecte. G. Butch scrie despre asta:

Clasificarea rezonabilă este, fără îndoială, o parte a oricărei științe. Michalsky și Stepp afirmă: „O sarcină integrală a științei este de a construi o clasificare semnificativă a obiectelor sau situațiilor observate. O astfel de clasificare facilitează foarte mult înțelegerea problemei principale și dezvoltarea ulterioară a teoriei științifice. De ce este atât de dificilă clasificarea? Atribuim acest lucru lipsei unei clasificări „perfecte”, deși, desigur, unele clasificări sunt mai bune decât altele. Coombs, Raffia și Thral susțin că „există tot atâtea moduri de a împărți lumea în sisteme de obiecte câte oameni de știință își asumă sarcina”. Orice clasificare depinde de punctul de vedere al subiectului. Flood și Carson dau un exemplu: „Regatul Unit... economiștii pot vedea ca o instituție economică, sociologii ca societate, ecologistii ca un colț de natură pe moarte, turiștii americani ca atracție turistică, liderii sovietici ca o amenințare militară, în cele din urmă. , cel mai romantic dintre noi , britanicii - ca pajiștile verzi ale patriei mamei.
"""Găsiți și selectați abstracții cheie.""" O abstracție cheie este o clasă sau un obiect care face parte din vocabularul domeniului. """Cea mai importantă valoare a abstracțiilor cheie constă în faptul că ele definesc limitele problemei noastre""": evidențiați ceea ce este inclus în sistemul nostru și, prin urmare, important pentru noi și eliminați excesul. Sarcina de a evidenția astfel de abstracții este specifică zonei problemei. Potrivit lui Goldberg, „alegerea corectă a obiectelor depinde de scopul aplicației și de gradul de detaliu al informațiilor care sunt prelucrate”.

După cum am observat, definirea abstracțiilor cheie implică două procese: descoperire și invenție. Descoperim abstracții ascultând experți în domeniu: dacă un expert vorbește despre asta, atunci această abstracție este de obicei foarte importantă. Prin inventare, creăm noi clase și obiecte care nu fac neapărat parte din domeniu, dar sunt utile în proiectarea sau implementarea unui sistem. De exemplu, un utilizator ATM spune „cont, retrage, depozit”; acești termeni fac parte din vocabularul domeniului. Proiectantul de sistem le folosește, dar le adaugă pe ale sale, cum ar fi baza de date, managerul de ecran, lista, coada și așa mai departe. Aceste abstracții cheie nu mai sunt create de domeniul subiectului, ci de design.

Cel mai puternic mod de a evidenția abstracțiile cheie este de a reduce problema la clase și obiecte deja cunoscute.

Așadar, paradigma orientată pe obiect devine o paradigmă de nivel înalt și domină principiile paradigmei de programare structurală, deoarece este angajată în modelarea realității, construind modele ale domeniilor de studiu în limbajul specialiștilor din aceste domenii. Dacă neglijezi acest lucru de dragul scrierii unui program bun care va fi ușor de modificat, extins, care va avea interfețe clare și module independente, vei reveni la nivelul paradigmei de programare structurată. Programul tău va fi bun pentru toată lumea, dar nu va fi posibil să-l înțelegi, deoarece nu va corespunde realității, va fi explicat în termeni cunoscuți doar de tine, iar un specialist care cunoaște domeniul de specialitate nu va putea înțelegeți programul fără ajutorul dvs. În final, dificultatea va scădea într-un interval foarte îngust, deși ai organizat un program bun. Dar este programul, nu modelul. Absența unui model, sau doar o reprezentare superficială a acestuia, vă va „exploda” programul bun din interior și nu vă va permite să îl dezvoltați și să îl mențineți în continuare în viitor. Când introduci clase ale căror abstracții nu există, când aceste clase sunt pur sistemice și nu au nimic de-a face cu tematica, când sunt introduse doar pentru a simplifica fluxurile de interacțiune ale altor clase - software-ul tău devine „cu barbă” și dacă nu se urmărește refactorizarea în spatele unor astfel de zone, la un moment bun, dezvoltarea software-ului tău se va opri și va deveni imposibil - vei ajunge la limita programării structurate (ți s-a părut că folosirea claselor și a obiectelor nu amenință tu?).

upd. M-am gandit, subiectul este acut, nu voi comenta. Am spus faptele în articol, dar nu vreau să alunec la nivelul unui holivar. Dacă acest lucru nu a ajutat să te gândești - ei bine, atunci înseamnă că nu ai avut noroc de data asta. Într-adevăr, va fi constructiv - dacă scrieți contraargumente într-un articol separat. Nu mă angajez să distrug stereotipurile de masă.

Da, și de asemenea, ca să fie clar - am decis să public după discuții aici Să programăm perceptronul lui Rosenblatt? , unde a devenit clar într-un mod evident că programarea funcțională, atunci când se construiește un model prost în OOP, funcționează mai rău ca niciodată. Iar faptul că se laudă cu super viteză este o ficțiune, de fapt, modelul corect este important. Pentru unele (nu multe astfel de sarcini comparativ) programarea funcțională poate avea succes, dar nu trebuie să fie folosită peste tot acolo unde nu face niciun folos. Ei bine, sau cam așa ceva - poți scrie piesa discutată acolo NUMAI într-un stil funcțional și astfel încât să funcționeze mai repede decât cu evenimentele OOP?

  • Serghei Savenkov

    un fel de recenzie „rare”... parcă s-ar grăbi undeva