A durat aproximativ o zi calendaristica pentru a implementa aceasta solutie. Pe parcursul dezvoltarii, am utilizat Git pentru a sincroniza munca si a pastra o copie de rezerva a progresului.
NOTE: Acest proces m-a ajutat sa exersez utilizarea Git si sa consolidez cunostintele despre managementul proiectelor software. De asemenea, am devenit mai confortabil cu organizarea si testarea proiectelor complexe.
Acest proiect implementeaza un sistem de gestionare a muzeelor, grupurilor de vizitatori si evenimentelor asociate. Se ocupa de adaugarea muzeelor, grupurilor, ghizilor si membrilor, precum si de gestionarea notificarilor pentru evenimentele organizate in muzee.
NOTE: Proiectul este conceput pentru a simula operatiuni reale legate de managementul vizitatorilor in muzee si ofera functionalitati de raportare, gestionare a exceptiilor si prioritizare.
In acest proiect, am utilizat mai multe Design Patterns-uri pentru a asigura o arhitectura scalabila, modulara si usor de intretinut:
- Factory Pattern – Implementat pentru clasa
Personsi subclaseleProfessorsiStudent, acest model permite crearea flexibila a instantelor fara a expune logica de instantiere directa, asigurand astfel o mai buna separare a responsabilitatilor. - Singleton Pattern – Utilizat pentru clasa
Database, acest model garanteaza existenta unei singure instante a bazei de date pe tot parcursul executiei aplicatiei, prevenind astfel conflictele si optimizand gestionarea conexiunilor. - Command Pattern – Implementat pentru procesarea comenzilor, acest model permite o mai buna organizare a codului, separand logica fiecarei comenzi si oferind flexibilitate in adaugarea de functionalitati noi fara a modifica codul existent.
- Observer Pattern – Aplicat in cadrul clasei
Museum, acest model permite notificarea automata a instantelor de tipGuideasociate, asigurand actualizarea acestora in timp real la schimbarile din muzeu. - Builder Pattern – Utilizat in clasele
LocationsiMuseum, acest model faciliteaza construirea obiectelor complexe pas cu pas, imbunatatind lizibilitatea codului si oferind flexibilitate in configurarea obiectelor.
Prin alegerea acestor Design Patterns-uri, proiectul beneficiaza de un cod mai bine structurat, usor de extins si intretinut, asigurand astfel scalabilitate si claritate in implementare.
Instantierea bazei de date. Primul argument dat ca input imi dicteaza directia pe care o iau in program:
- fir museum, groups sau listener. Al doilea argument reprezinta path-ul fisierelor cu care vom lucra. Initializarea fisierelor de intrare si iesire pentru cazul in care am 4 argumente la rulare.
- Directia in care voi avea doar comenzi ce tin doar de muzee.
- Directia in care voi avea doar comenzi ce tin de grup.
- Directia in care voi avea doar comenzi legate de evenimente.
Deschiderea fisierului din care voi citi.
Deschiderea fisierului in care voi scrie.
Prima linie o citesc si nu o folosesc deoarece prima linie reprezinta argumentele pe care ulterior le voi citi si in ordinea in care vor aparea in fisierul de input.
Citesc pana fisierul se termina.
Imi impart argumentele dupa separatorul |.
In directia de muzeu, singura comanda pe care o pot primi este addMuseum.
Imi creez instanta si o salvez (plus afisarea in fisier).
Deschid fisierul de intrare.
Deschid fisierul de iesire, in care imi voi scrie datele prelucrate.
Citesc prima linie care contine descrierea ordinii si a argumentelor din fisierul de intrare.
Folosesc separatorul |.
Pentru grup, avem mai multe comenzi pe care le citesc din fisierul de intrare si ulterior, pentru fiecare comanda, aleg executia programului conform comenzilor pe care comanda le presupune.
Apelez celelalte comenzi deja implementate pentru seturile de date corespunzatoare, acestea fiind crearea muzeelor si a grupurilor, ca apoi sa pot adauga si evenimente unui muzeu, ce va notifica fiecare ghid.
Deschid fisierul de intrare.
Deschid fisierul de iesire, in care imi voi scrie datele prelucrate.
Citesc prima linie care contine descrierea ordinii si a argumentelor din fisierul de intrare.
Folosesc separatorul |.
Directia denumita de mine listener are doar o comanda, aceea fiind addEvent, lucru pe care l-am apelat.
Caut muzeul cu codul dat si notific fiecare ghid inregistrat la acel grup.
In cazul in care campul email este null, ii asignez stringul "null" pentru a-l putea afisa ca fiind null.
Fac o cautare a grupului dupa muzeul la care este asignat si daca exista intervalul de timp la muzeu acelasi cu cel declarat.
In cazul in care grupul nu exista, fiind ghidul adaugat primul, formez grupul.
Daca rolul persoanei pe care incerc sa o adaug nu este cel de profesor, arunc exceptia GuideTypeException.
Daca cele de sus nu sunt indeplinite, dar am ghid deja asignat grupului, asta inseamna ca voi arunca exceptia GuideExistsException.
Daca nu exista nici ghid, creez un ghid de tip profesor cu ajutorul design pattern-ului factory.
Adaug ghidul grupului si in lista de ghizi ai unui anumit muzeu, pentru a-mi facilita o notificare mai usoara ulterior in momentul in care se anunta un eveniment.
Fac o cautare a grupului dupa muzeul la care este asignat si daca exista intervalul de timp la muzeu acelasi cu cel declarat.
Daca grupul nu exista, voi arunca eroarea GroupNotExistsException.
Daca grupul are mai mult de 10 membri, acesta nu mai poate suporta membri noi, asa ca voi arunca exceptia GroupThresholdException.
Altfel, creez persoana cu ajutorul design pattern-ului factory si o adaug in lista de membri corespunzatoare.
Verific daca am destui parametri ca sa pot apela constructorul de baza, plus constructorul de baza pentru locatie. Aici initializez variabilele respective cu null in cazul in care ce am citit este invalid si vreau totusi sa evit o exceptie aruncata, acestea fiind campuri optionale. La fel si aici, citesc numele managerului doar daca argumentul acestuia este nenul. Apelez builderul pentru locatie si builderul pentru muzeu, la care ulterior apelez si seterele pentru campurile optionale. Adaug muzeul in baza de date.
Fac o cautare a grupului dupa muzeul la care este asignat si daca exista intervalul de timp la muzeu acelasi cu cel declarat.
Daca grupul nu exista, voi arunca eroarea GroupNotExistsException.
Daca ghidul pe care incerc sa-l caut este de fapt un student, incetez cautarea si arunc exceptia GuideTypeException.
Apelez functia care imi gaseste ghidul grupului primit si verific daca datele ghidului corespund cu cele ale ghidului cautat.
Daca gasesc ghidul, afisez raspunsul.
Altminteri, afisez faptul ca ghidul cautat nu exista.
Fac o cautare a grupului dupa muzeul la care este asignat si daca exista intervalul de timp la muzeu acelasi cu cel declarat.
Daca grupul nu exista, voi arunca eroarea GroupNotExistsException.
Caut in lista de membri ai grupului deja gasit sa vad daca gasesc un membru care are aceleasi calitati ca cel pe care incerc sa-l gasesc.
Daca il gasesc, afisez succesul si opresc executia programului aici.
Altminteri, afisez faptul ca membrul nu exista in lista mea.
Fac o cautare a grupului dupa muzeul la care este asignat si daca exista intervalul de timp la muzeu acelasi cu cel declarat.
Daca grupul nu exista, voi arunca eroarea GroupNotExistsException.
Daca grupul nu are ghid, arunc exceptia PersonNotExistsException.
Altminteri, fac o copie a instantei ghid pentru a afisa dupa eliminare datele despre ea, elimin ghidul si apoi afisez succesul.
Fac o cautare a grupului dupa muzeul la care este asignat si daca exista intervalul de timp la muzeu acelasi cu cel declarat.
Daca grupul nu exista, voi arunca eroarea GroupNotExistsException.
Caut in lista de membri ai grupului deja gasit sa vad daca gasesc un membru care are aceleasi calitati ca cel pe care incerc sa-l gasesc.
Daca il gasesc, il elimin, afisez succesul si opresc executia programului aici.
Altminteri, arunc exceptia PersonNotExistsException.
Realizez notificarea ghizilor salvati in lista guides.
Metoda care primeste notificarea de la muzeu si afiseaza in fisier faptul ca a fost notificata.