Table of Contents
Tema de Casă 1
Implementarea modului de aprovizionare (SCM - Supply Chain Management) pentru un sistem informatic dedicat unui lanț de restaurante
Termen de Predare: 27 noiembrie 2015, 23:55
Pondere: 10 p / 35
Obiective
Obiectivul temelor de casă este reprezentat de implementarea unui sistem informatic performant şi scalabil pentru gestiunea resurselor unei societăți comerciale de dimensiuni mari. În acest an universitar, organizaţia pentru care se va proiecta şi dezvolta acest pachet de programe este un lanț de restaurante.
Se va realiza implementarea mai multor module din cadrul aplicației ERP, pe parcursul a trei etape independente.
În cadrul acestei etape, sistemul informatic va fi capabil să interogheze servicii care rulează în alte maşini virtuale şi ale căror funcţionalităţi le cunoaşte, acestea fiind accesibile prin intermediul unei reţele de calculatoare.
După rezolvarea temei de casă, studentul va fi capabil să:
- proiecteze o aplicaţie având o structură distribuită pe componente care poate rula pe maşini diferite;
- modeleze comunicaţia între componentele distribuite ale aplicaţiei.
Cunoştinţele necesare pentru rezolvarea temei de casă sunt:
- programarea în limbajul Java;
- proiectarea și dezvoltarea unei baze de date folosind sistemul de gestiune MySQL;
- folosirea unei interfețe de programare pentru accesarea informațiilor dintr-o sursă de date (Java Database Connectivity / Java Persistence API);
- utilizarea tehnologiei RMI (Remote Method Invocation) pentru apelarea unor metode aparţinând unor obiecte existente într-o altă maşină virtuală, a căror definiţie se consideră cunoscută.
Enunț
Se dorește implementarea modulului de aprovizionare (SCM - Supply Chain Management) pentru un sistem informatic destinat gestiunii activității dintr-un lanț de restaurante.
Pentru a putea asigura meniul pentru o anumită zi, restaurantul trebuie să se aprovizioneze cu o serie de produse culinare, care pot fi livrate de anumiți furnizori. Informațiile cu privire la alimentele care pot fi comandate precum și transmiterea de solicitări pentru livrarea acestora sunt realizate prin intermediul unui agent de intermediere a comunicației, care face legătura dintre restaurant și diferiții producători. Acesta poate fi interogat pentru a se obține lista agenților economici către care pot fi plasate comenzi, lista produselor pe care aceștia le comercializează (împreună cu data de livrare și prețul lor), pentru a le rezerva pentru anumite perioade de timp (respectiv pentru a anula rezervarea), precum și pentru a plasa o comandă fermă.
1. Un furnizor de produse alimentare va interacționa doar cu agentul de intermediere a comunicației cu lanțul de restaurante. Accesul la metodele expuse va fi permis doar în situația în care între aceste entități este stabilită o legătură, în acest sens fiind implementat un meniu în mod text în cadrul componentei producător prin care vor fi accesate funcționalitățile de înregistrare, respectiv de deînregistrare de la nivelul agentului de intermediere.
Funcționalitățile pe care le expune un către agentul de intermediere sunt:
a) metoda getSupplierInfo()
oferă informații cu privire la producător:
- parametri: -;
- valoare întoarsă: un obiect de tip
Supplier
care conține datele prin care un furnizor de produse alimentare este identificat: denumire și descriere.
public Supplier getSupplierInfo();
b) metoda getProductList()
furnizează lista de materii prime pe care le comercializează producătorul respectiv:
- parametri: -;
- valoare întoarsă: o listă de obiecte de tip
Product
, caracterizat prin preț unitar, cantitate disponibilă, unitate de măsură precum și un termen de fabricație (în situația în care un ingredient nu este disponibil în stoc în cantitatea solicitată, acesta poate fi livrat într-un interval de timp indicat de acest parametru, exprimat în număr de zile calendaristice), toate aceste informații fiind gestionate prin intermediul unei baze de date dedicate pentru fiecare agent comercial în parte:
public List<Product> getProductList();
c) metoda getOffer()
permite obținerea unei oferte, pentru o listă de solicitări:
- parametru: o listă de obiecte de tip
Demand
, acestea conținând denumirea unui produs precum și cantitatea acesteia; - valoare întoarsă: un obiect de tip
Offer
, constând în prețul total și numărul de zile calendaristice după care lista de solicitări poate fi onorată (dacă întregul volum, pentru toate ingredientele, este disponibil în stoc, acesta este 0, altfel se determină numărul de zile după care toate materiile prime ar putea fi furnizate):
public Offer getOffer(List<Demand> demands);
null
.
d) metoda makeReservation()
realizează o rezervare pe baza unei liste de solicitări, generându-se oferta corespunzătoare:
- parametri: un identificator unic, pe baza căruia rezervarea va putea fi referită la nivelul furnizorului și o listă de obiecte de tip
Demand
reprezentând lista de solicitări; - valoare întoarsă: un obiect de tip
Offer
reprezentând oferta furnizorului; este necesar să se genereze un astfel de rezultat deoarece acesta conține informații actualizate la momentul la care este realizată rezervarea respectivă.
public Offer makeReservation(int reservationId, List<Demand>);
e) metoda cancelReservation()
anulează o rezervare prealabilă:
- parametru de intrare: un identificator unic prin intermediul căruia este referită comanda respectivă;
- valoare întoarsă: o valoare de tip adevărat / fals după cum operația a fost realizată cu succes, respectiv cu eșec.
public boolean cancelReservation(int reservationId);
f) metoda issueSupplyOrder()
plasează o comandă de aprovizionare pe baza unei rezervări:
- parametru de intrare: un identificator unic prin intermediul căruia este referită comanda respectivă;
- valoare întoarsă: o valoare de tip adevărat / fals după cum operația a fost realizată cu succes, respectiv cu eșec.
public boolean issueSupplyOrder(int reservationId);
2. Un agent de intermediere facilitează comunicația dintre un furnizor și lanțul de restaurante, expunând către fiecare dintre acestea anumite funcționalități:
CĂTRE FURNIZOR
a) metoda registerSupplier()
permite înregistrarea unui furnizor la agentul de intermediere; doar în cazul în care furnizorul este înregistrat la agentul de intermediere, acesta poate fi interogat cu privire la produsele pe care le comercializează; metoda are ca semnătură:
- parametri: un obiect de tip
Supplier
conținând informațiile prin care furnizorul este identificat; - valoarea întoarsă: un identificator prin care furnizorul este referit în mod unic la nivelul agentului de intermediere.
public int registerSupplier(Supplier supplier);
b) metoda unregisterSupplier()
permite deînregistrarea unui furnizor de la agentul de intermediere; în acest moment, toate informațiile stocate referitor la nivelul agentului de intermediere cu privire la furnizorul respectiv sunt eliminate; metoda are semnătura:
- parametru: identificatorul unic prin care furnizorul este referit de agentul de intermediere;
- valoarea întoarsă: o valoare de tip adevărat / fals, care indică dacă operația a fost realizată cu succes, respectiv cu eșec.
public boolean unregisterSupplier(int registrationId);
CĂTRE LANȚUL DE RESTAURANTE
a) metoda getSupplierList()
furnizează o listă cu furnizorii care pot fi accesați la un moment dat:
- parametri: -;
- valoare întoarsă: o listă de obiecte de tip
Supplier
, conținând informațiile prin care furnizorul este identificat.
public List<Supplier> getSupplierList();
b) metoda getProducts()
determină lista tuturor produselor care pot fi comandate, pentru fiecare furnizor în parte:
- parametri: -;
- valoare întoarsă: un obiect de tip
Map
având drept cheie un obiect de tipSupplier
iar ca valoare o listă de obiecte de tipProduct
reprezentând alimentele corespunzătoare furnizorului în cauză.
public Map<Supplier, List<Product>> getProducts();
c) metoda getOffers()
generează ofertele corespunzătoare fiecărui furnizor în parte, pentru o anumită listă de solicitări:
- parametru: o listă de obiecte de tip
Demand
, reprezentând o listă de solicitări; - valoare întoarsă: un obiect de tip
Map
având drept cheie un obiect de tipSupplier
iar ca valoare o listă de obiecte de tipOffer
reprezentând ofertele corespunzătoare furnizorului în cauză.
public Map<Supplier, Offer> getOffers(List<Demand> demands);
d) metoda makeReservation()
realizează o rezervare, la nivelul unui furnizor, pentru o listă de solicitări:
- parametri: un obiect de tip
Supplier
, conținând informațiile prin care furnizorul este identificat și o listă de obiecte de tipDemand
reprezentând lista de solicitări; - valoare întoarsă: un identificator unic (atât la nivelul agentului de intermediere cât și la nivelul furnizorului) prin care rezervarea va putea fi referită sau -1 în situația în care rezervarea nu a putut fi realizată (nu poate fi generată o ofertă pe baza listei de solicitări de către producătorul în cauză).
public int makeReservation(Supplier supplier, List<Demand> demands);
e) metoda cancelReservation()
anulează o rezervare prealabilă:
- parametru: un identificator unic, prin care rezervarea este referită atât la nivelul agentului de intermediere cât și la nivelul furnizorului;
- valoare întoarsă: o valoare de tip adevărat / fals după cum operația a fost realizată cu succes, respectiv cu eșec.
public boolean cancelReservation(int reservationId);
f) metoda issueSupplyOrder()
plasează o comandă de aprovizionare pe baza unei rezervări:
- parametru de intrare: un identificator unic prin intermediul căruia este referită comanda respectivă;
- valoare întoarsă: o valoare de tip adevărat / fals după cum operația a fost realizată cu succes, respectiv cu eșec.
public boolean issueSupplyOrder(int reservationId);
3. Un lanț de restaurante accesează operațiile pe care le oferă agentul de intermediere a comunicației cu producătorii de produse alimentare pentru a realiza aprovizionarea cu produse culinare în vederea asigurării activității operaționale.
Pentru fiecare dată calendaristică, trebuie asigurată pregătirea unui meniu, format din mai multe feluri de mâncare. Acestea sunt caracterizate prin tip (aperitiv, fel principal, desert), denumire precum și ingrediente (denumire și cantitate, pentru care este asociată și o unitate de măsură). De asemenea, pentru fiecare meniu se indică și cantitățile din fiecare tip de fel de mâncare care vor fi pregătite pentru data calendaristică respectivă, astfel încât să se cunoască volumul de preparate care trebuie procurate. Un meniu poate conține mai multe feluri de mâncare de același tip, însă acestea vor fi preparate în același număr de porții. Pentru fiecare meniu se reține și starea sa (dacă s-a realizat procesul de aprovizionare corespunzător sau nu).
Modul de operare la nivelul lanțului de restaurante implică obținerea listelor de oferte de la producători, selectarea unui furnizor dintre cei care pot asigura necesarul de ingrediente, realizarea unei rezervări și plasarea unei comenzi de aprovizionare pe baza acesteia.
Arhitectura sistemului informatic va fi prin urmare formată din trei componente care comunică între ele, dintre care una (agentul de intermediere a comunicației) expune funcționalități de tip server atât către componenta de tip furnizor cât și către componenta de tip lanț de restaurante. În această situație, se va asigura faptul că pentru fiecare entitate vor fi accesibile doar metodele specifice, fără a se expune și operațiile aferente altor aplicații.
Precizări suplimentare
NU este permisă folosirea altor tehnologii cu excepția celor specificate în enunţ.
Persistența informațiilor la nivelul componentelor va fi asigurată prin stocarea acestora în baze de date dedicate.
Pentru un producător, datele specifice (denumirea și descrierea) vor fi precizate sub formă de parametri în linia de comandă în momentul lansării sale în execuție.
Perioada pentru care o rezervare este menținută se măsoară în număr de zile calendaristice și se exprimă sub formă de constantă la nivelul codului sursă.
Metodele de la nivelul agentului de intermediere vor accesa funcționalitățile cu acceeași denumire de la nivelul producătorilor de produse alimentare, în unele situații fiind necesară accesarea întregii liste a furnizorilor care pot fi contactați la un moment dat. Într-un astfel de model, în care componentele sunt strâns cuplate, toate operațiile sunt sincrone (se blochează până se transmite un rezultat de la metoda invocată). Accesul la resursele care pot fi referite de mai multe fire de execuție concomitent trebuie să se realizeze sincronizat.
Semnăturile metodelor accesibile la distanță pot suferi modificări în funcție de necesități, cu respectarea funcționalității descrise.
Nu este necesar să se implementeze o interfață grafică pentru testarea aplicațiilor, fiind suficient un meniu în mod text care să permită introducerea unui număr de opțiuni corespunzător numărului de metode pe care o componentă le poate accesa la distanță.
Orice specificaţie care nu este menţionată mai sus reprezintă decizie de implementare. Puteţi considera orice simplificare în condiţiile în care enunţul nu precizează altfel.
Barem de corectare și notare
Punctaj | Criterii de acordare |
---|---|
2 p | proiectarea tabelelor în baza de date pentru fiecare componentă (furnizor, agent de intermediere, lanț de restaurante) • conformitatea structurii conceptuale a bazei de date cu o formă normală: 40% • definirea de chei primare, chei străine (legături între toate tabelele bazei de date), constrângeri de integritate pentru formatul atributelor: 25% • populare corespunzătoare: 35% |
1,50 p | proiectarea metodelor corespunzătoare componentelor de tip server • componenta furnizor: 35% • componenta agent de intermediere a comunicației (segregarea interfețelor!!!): 65% |
2 p | implementarea metodelor corespunzătoare componentei furnizor • getSupplierInfo() : 5%• getProductList() : 10%• getOffer() : 20%• makeReservation() : 35%• cancelReservation() : 15%• issueSupplyOrder() : 15% |
2 p | implementarea metodelor din agentul de intermediere a comunicației • getSupplierList() : 10%• getProducts() : 20%• getOffers() : 20%• makeReservation : 30%• cancelReservation : 10%• issueSupplyOrder() : 10% |
1,50 p | apelarea metodelor disponibile la distanță din cadrul componentelor de tip client • componenta lanț de restaurante: 55% • componenta agent de intermediere a comunicației: 30% • componenta furnizor: 15% |
1 p | modularizare • structura aplicaţiei: 40% • aspecte legate de eficiență: 40% • lizibilitatea codului, comentarii, README: 20% |
BONUS. Se pot obţine punctaje suplimentare, astfel:
- 0,50 p – predarea şi prezentarea temei cu o săptămână mai devreme (înainte de 20.11.2015, 23:55);
- 0,50 p - modificarea modului de funcționare a metodei
getOffers()
de la nivelul agentului de intermediere a comunicației, astfel încât acesta să mai primească un parametru, de tip întreg (criteria
) care să specifice criteriul în funcție de care va fi determinată o singură ofertă, acesta putând fi:BEST_PRICE
- cel mai mic preț total, respectivBEST_DELIVERY_TIME
- cel mai mic termen de livrare; în situația în care există mai mulți furnizori care întrunesc aceste criterii, va fi ales unul aleator; - 1,00 p - modificarea modului de funcționare a metodei
getOffers()
de la nivelul agentului de intermediere a comunicației, astfel încât să nu mai fie necesar ca acesta să apeleze metode la distanță în acest moment; în schimb, se va implementa o zonă de memorie tampon în care vor fi stocate toate informațiile cu privire la produsele comercializate de furnizori și la cantitățile în care acestea se găsesc, pe baza invocărilor anterioare; acestea vor fi utilizate pentru a determina lista cu oferte corespunzătoate fiecărui furnizor în parte, în situația în care va fi transmis un parametru de tip adevărat / false (fromCache
); aceasta implică faptul că o ofertă ar putea să nu fie generată pentru un producător fie din cauza faptului că acesta nu a mai fost accesat fie din cauza faptului că informațiile cu privire la stocurile acestuia nu sunt actualizate.
Condiții de realizare și predare
Tema va fi realizată individual şi va fi prezentată în cadrul laboratorului, până la sfârşitul semestrului. Neprezentarea temei de casă sau un rezultat nesatisfăcător al prezentării (necunoașterea funcționalității aplicației / codului sursă, imposibilitatea de a răspunde la întrebări) atrag după sine anularea punctajului corespunzător acesteia. În cadrul prezentării veţi specifica succint funcţionalităţile pe care le-aţi dezvoltat şi veţi răspunde la întrebări cu privire la modul de implementare al acestora.
Tema va trebui transmisă sub forma unui mesaj la adresa de poștă electronică aipi2015@andreirosucojocaru.ro sub forma unei arhive de tip .zip (având denumirea Grupa34XCX_NumePrenume_Tema1.zip) care să conţină script-ul pentru crearea şi popularea tabelelor din bazele de date (numele bazei de date fiind Grupa34XCX_NumePrenume pentru lanțul de restaurante, respectiv Grupa34XCX_NumePrenume_Furnizor pentru fiecare furnizor) – în rădăcina, sursele aplicaţiilor (proiecte Eclipse / NetBeans), configurațiile de rulare (parametrii java.rmi.server.codebase
, java.rmi.server.hostname
, java.security.policy
), precum şi un README în care să explicaţi funcționalitățile dezvoltate, problemele întâlnite și modul de soluționare a acestora. Subiectul utilizat va fi [Tema1][Grupa34XCX][NumePrenume]. Temele care nu respectă convențiile de nume indicate nu vor fi luate în considerare. Prezentarea se poate face numai după ce tema a fost predată sub această formă.
Temele vor fi comparate prin aplicaţii specializate pentru a se depista eventualele fraude. În această situaţie, întreg punctajul pe parcursul semestrului va fi anulat, studenţii implicaţi (atât originalul, cât şi copia / copiile) fiind obligaţi să repete disciplina – cu taxă – în anul universitar următor.