Jump to content

SUBIECTE NOI
« 1 / 5 »
RSS
Recomandare bicicleta copil 5 ani.

Recomandare kit automat acces usa

[email][nvidia] Your GeForce NOW ...

Site nesigur
 Baghetele ornamentale intre foile...

O recomandare pentru o camera ful...

Pareri magazin online quickmobile?

Unde gasesc banane albastre?
 Despre compania de aministrare Sq...

Durere taietura deget dupa 2 luni

Dalți gravare lemn

Didgeridoo
 Motorola Edge 50 Ultra

Gaura perete apartament cu evitar...

Orientare antena prime focus

Problema conectare mail yahoo
 

Baze de date embedded – exercitiu practic (pentru programatori mid-level)

* * * - - 2 votes
  • Please log in to reply
183 replies to this topic

#73
OriginalCopy

OriginalCopy

    I'm harmful, fear me please! :))

  • Grup: Senior Members
  • Posts: 27,268
  • Înscris: 10.08.2006

View Postjegmihai, on 20 septembrie 2018 - 11:21, said:

Am revenit cu un update, am adăugat noul Storage Plugin.

Am avut în vedere următoarele lucruri:
  • ContactsSQLiteRepository să nu aibă metode publice care i-ar putea corupe state-ul. Prin urmare, am decis ca toate operațiile de inițializare să fie făcute în constructorul default.
  • StoragePlugin să expună doar o interfață abstractă și nu o clasă concretă.
Pe de altă parte, din cauza/datorită acestui approach, metodele specifice IPlugin, respectiv init() și run(), au devenit cam...nefolositoare.
Atunci sterge-le. Daca va fi nevoie de ele, ne vom gandi la abordari la momentul oportun.

Vezi si ce ti-a zis dani: "shutdown" devine destructor.

Baza de date trebuie instantiata in db plugin, si conexiunea inchisa in destructorul lui db plugin.

Clasele pe care le ai sunt in general ok (mai e nevoie de lucru, dar directia e buna). Cea mai mare problema e ca nu ai o piramida, un arbore, in arhitectura, ci doar clase care atarna in pom, si pomul in aer.

Imagineaza-ti o piramida construita din straturi (layers). La varful piramidei se afla aplicatia, care e doar una (ma rog, mici varfuri, pentru fiecare entry point - dar momentan ai doar un main.cpp).

Application manageriaza layerele de sub ea, adica plugins, fiecare plugin manageriaza resursele de sub el, adica resursele (conexiune la baza de date, repositories, dialoguri, etc).

Conexiunea la baza de date manageriaza lucrurile specifice unei baze de date, dialogurile manageriaza input boxes, s.a.m.d.

=> o structura arborescenta.

Nu vrei sa ai puncte de acces ad-hoc: daca ai nevoie de ceva de la db, in ui fiind, trebuie sa treci prin db plugin mai intai. Punctul de contact dintr-un plugin intr-altul e mereu printr-un obiect IPlugin.

Layerele de deasupra sunt responsabile pentru copii lor.

#74
jegmihai

jegmihai

    Senior Member

  • Grup: Senior Members
  • Posts: 11,536
  • Înscris: 03.09.2013
Dacă shutDown() va deveni destructor voi fi nevoit să mă conformez cu Rule Of Five. Totuși, mă gândesc să dezactivez copy + move constructors, respectiv assignment operators.

Dpdv arhitectural presupun că te referi la așa ceva: https://upload.wikim...Version.svg.png

Sau chiar la ceva mai complex.

#75
jegmihai

jegmihai

    Senior Member

  • Grup: Senior Members
  • Posts: 11,536
  • Înscris: 03.09.2013
Sau așa?

[ https://dzone.com/storage/temp/4277164-layered-architecture-overview.png - Pentru incarcare in pagina (embed) Click aici ]

#76
OriginalCopy

OriginalCopy

    I'm harmful, fear me please! :))

  • Grup: Senior Members
  • Posts: 27,268
  • Înscris: 10.08.2006
Aia este arhitectura fluxului de date, si da, asa sunt mutate datele de colo colo in aplicatia ta.

Eu vorbeam despre arhitectura structurala a codului. Problema cu "arhitectura" e ca ai atatea arhitecturi cati programatori, fiecare da cate un nume la cate ceva, si fiecare pune accentul pe unele aspecte mai mult sau mai putin. In principiu, mai toate respecta aceleasi principii fundamentale, pe care le aplicam si noi aici (si principii au tot fost numite deja pe acest topic).

Exemple de denumiri:

https://nathanjohnst...e-architecture/

https://jeffreypaler...tecture-part-1/

https://medium.freec...re-990c014448d2

DDD introduce ceva idei care pot fi combinate cu cele de mai sus: https://en.wikipedia...n-driven_design



Ce faci aici deocamdata e mai mult "onion architecture", dar poti sa o numesti si "hexagonal", si deja folosesti un termen folosit de obicei in cercurile DDD (repository). E un melanj. Numele nu conteaza pana la urma urmei, adopti idei si concepte si le implementezi in functie de nevoi.

Poti sa mulezi ce faci aici pe oricare dintre ele oricum, sau chiar doar anumite componente poti sa le faci dupa anumite strategii - de exemplu chiar DDD recomanda sa nu faci "DDD in toata aplicatia", ci doar unde merita.

E irelevant, really. Aici vrem doar ca tu sa ai o fundatie foarte limitata dar destul de robusta incat cercetarile si cartile pe care le vei citi sa pot fi integrate usor in acest "framework of mind" pe care il construiesti acum. Adica: sa citesti acele articole si carti, si sa "vezi codul in fata ochilor", doar citind ideile abstracte ale arhitectilor respectivi.

Dupa ce iti iei zborul, iti vei dezvolta propriul corp de idei.

Addendum: pe scurt, momentan ai directia dependintelor ca in onion, dar separarea curata (prin plugins) din hexagonal, si o idee din DDD (repository), dar vom mai adauga cel putin inca una din DDD: value objects.

Edited by OriginalCopy, 20 September 2018 - 15:56.


#77
jegmihai

jegmihai

    Senior Member

  • Grup: Senior Members
  • Posts: 11,536
  • Înscris: 03.09.2013

View PostOriginalCopy, on 20 septembrie 2018 - 16:00, said:

dar vom mai adauga cel putin inca una din DDD: value objects.
În ce context?

Contact însuși ar putea fi un value object.

Între timp am testat StoragePlugin, funcționează OK.

Acum sunt nevoit să mă apuc de refactoring pe partea de UI.

#78
OriginalCopy

OriginalCopy

    I'm harmful, fear me please! :))

  • Grup: Senior Members
  • Posts: 27,268
  • Înscris: 10.08.2006
FirstName, LastName, PhoneNumber, ContactId, ar fi cateva exemple de value objects.

Introduse peste tot pe unde variabilele se numesc first_name, etc.

Avantaj: iti protejeaza domeniul de date corupte. In constructorul value objects arunci o exceptie daca datele sunt invalide. Deoarece toate componentele accepta doar value objects (faci semnatura metodelor sa dicteze asta), protejezi toate componentele de coruperi simple, sintactice.

Nu te protejeaza de date corupte semantic, de exemplu un nr de telefon detinut de doua contacte.

Alt avantaj: e mai usor sa cauti. Una e sa cauti dupa "string", alta dupa "FirstName".

Si inca unul: expresivitatea domain model (mentionat intr-o postare anterioara si care e avantajul).

#79
jegmihai

jegmihai

    Senior Member

  • Grup: Senior Members
  • Posts: 11,536
  • Înscris: 03.09.2013
Value objects le voi face immutable. Este redundant să le pasez prin const&?

Edited by jegmihai, 20 September 2018 - 20:59.


#80
OriginalCopy

OriginalCopy

    I'm harmful, fear me please! :))

  • Grup: Senior Members
  • Posts: 27,268
  • Înscris: 10.08.2006
Cel mai probabil compilatorul poate face niste optimizari. Nu stiu sigur, nu am mai programat de ceva vreme in C++.

dani.user e maestru la d-astea.

Personal as folosi const& oricum, pentru expresivitatea codului.

#81
jegmihai

jegmihai

    Senior Member

  • Grup: Senior Members
  • Posts: 11,536
  • Înscris: 03.09.2013

View PostOriginalCopy, on 20 septembrie 2018 - 20:23, said:

In constructorul value objects arunci o exceptie daca datele sunt invalide.
Ce înțelegi prin invalide?

LastName este invalid dacă conține și 2-3 cifre(pe lângă litere)?

Edited by jegmihai, 20 September 2018 - 21:49.


#82
OriginalCopy

OriginalCopy

    I'm harmful, fear me please! :))

  • Grup: Senior Members
  • Posts: 27,268
  • Înscris: 10.08.2006

View Postjegmihai, on 20 septembrie 2018 - 21:48, said:

Ce înțelegi prin invalide?

LastName este invalid dacă conține și 2-3 cifre(pe lângă litere)?
De exemplu, da. La fel si un sir gol sau constituit din caractere neprintabile.

Value objects sunt parte din domain model, deci in ele implementezi regulile de business relevante. Si regulile sintactice tot reguli de business sunt.

Aici mostra de proiect la care lucreaza un coforumist: https://github.com/w...tree/master/src

Clase ca GameStatus, MapCoordinate si Mark sunt value objects.

#83
jegmihai

jegmihai

    Senior Member

  • Grup: Senior Members
  • Posts: 11,536
  • Înscris: 03.09.2013
Offtopic, m-am uitat peste GameStatus și mă duce cu gândul la State.

Tehnic vorbind, acea clasă reprezintă un state al jocului, însă ați ales sa o denumiți astfel datorită faptului că face parte din domain model?

View PostOriginalCopy, on 20 septembrie 2018 - 22:19, said:

De exemplu, da. La fel si un sir gol sau constituit din caractere neprintabile.
Intrebarea următoare este legată de algoritmică.

Pattern matching se pliază aici?

#84
OriginalCopy

OriginalCopy

    I'm harmful, fear me please! :))

  • Grup: Senior Members
  • Posts: 27,268
  • Înscris: 10.08.2006
Da.

Da.

#85
jegmihai

jegmihai

    Senior Member

  • Grup: Senior Members
  • Posts: 11,536
  • Înscris: 03.09.2013
Am revenit cu un update în acest sens.

De asemenea, am adăugat un video în care evidențiez partea cu id-urile. Așa funcționează el momentan, fără să-i fi adăugat Repository-ul ca storage.

https://streamable.com/t539t

#86
OriginalCopy

OriginalCopy

    I'm harmful, fear me please! :))

  • Grup: Senior Members
  • Posts: 27,268
  • Înscris: 10.08.2006
UX lasa de dorit, dar nu m-as apleca asupra lui acum.

Vezi ca ai litera Q (QString) in value objects. Efectiv nu ai voie cu #include <q...> in directorul src/phonebook/ - e foarte simplu.

Si nu arunci exceptii in constructori. E foarte important, altfel cel mai important avantaj al VO s-a dus pe apa sambetei: VO iti protejeaza domeniul de valori invalide.

Decat sa iti impingi QString-ul cu forta in domain model, mai bine implementezi operator std::string pentru value objects si lucrezi doar cu value objects.

Orice ai alege, asta nu e ok:

Contact(QString const& lastName, QString const& firstName, QString const& phoneNumber) noexcept;


#87
jegmihai

jegmihai

    Senior Member

  • Grup: Senior Members
  • Posts: 11,536
  • Înscris: 03.09.2013

View PostOriginalCopy, on 21 septembrie 2018 - 14:23, said:

Efectiv nu ai voie cu #include <q...> in directorul src/phonebook/ - e foarte simplu.
Aveam în minte regula respectivă, însă mă gândeam la orice alt QObject decât QString. Vina mea.

View PostOriginalCopy, on 21 septembrie 2018 - 14:23, said:

Si nu arunci exceptii in constructori.
Cred că am înțeles greșit ce ai spus aici.

View PostOriginalCopy, on 20 septembrie 2018 - 20:23, said:

In constructorul value objects arunci o exceptie daca datele sunt invalide.


#88
OriginalCopy

OriginalCopy

    I'm harmful, fear me please! :))

  • Grup: Senior Members
  • Posts: 27,268
  • Înscris: 10.08.2006
Exceptie in constructor: https://github.com/w...rc/Mark.php#L28

Datorita exceptiei, nu poti construi VOs invalide. Si datorita faptului ca celelalte modele accepta exclusiv VO, nu poti infecta niciun alt model cu date invalide (sintactic).

#89
jegmihai

jegmihai

    Senior Member

  • Grup: Senior Members
  • Posts: 11,536
  • Înscris: 03.09.2013
Excepția o arunc din metoda validate() care este apelată în constructor.

https://github.com/I...astName.cpp#L10

#90
OriginalCopy

OriginalCopy

    I'm harmful, fear me please! :))

  • Grup: Senior Members
  • Posts: 27,268
  • Înscris: 10.08.2006
Cel putin o alta clasa in care m-am uitat nu arunci exceptie.

Anunturi

Bun venit pe Forumul Softpedia!

0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

Forumul Softpedia foloseste "cookies" pentru a imbunatati experienta utilizatorilor Accept
Pentru detalii si optiuni legate de cookies si datele personale, consultati Politica de utilizare cookies si Politica de confidentialitate