ific: Prof. Dr. Ing. Zamfirescu Bălă Constantin Îndrumător: Prof. Dr. Ing. Zamfirescu Bălă Constantin Absolvent: Schiau Andreea-Roxana Specializarea… [605912]

UNIVERSITATEA “LUCIAN BLAGA” DIN SIBIU

FACULTATEA DE INGINERIE

DEPARTAMENTUL DE CALCULATOARE ȘI INGINERIE ELECTRICĂ

PROIECT DE DIPLOMĂ

Conducător
ș
tiin
ț
ific: Prof. Dr. Ing. Zamfirescu Bălă Constantin

Îndrumător: Prof. Dr. Ing. Zamfirescu Bălă Constantin

Absolvent: [anonimizat],

2019 –

UNIVERSITATEA “LUCIAN BLAGA” DIN SIBIU

FACULTATEA DE INGINERIE

DEPARTAMENTUL DE CALCULATOARE ȘI INGINERIE ELECTRICĂ

ALOCAREA RESURSELOR

INDIVIZIBILE –

ORGANIZAREA

FESTIVALURILOR DE MODĂ

Conducător
ș
tiin
ț
ific: Prof. Dr. Ing. Zamfirescu Bălă Constantin

Îndrumător: Prof. Dr. Ing. Zamfirescu Bălă Constantin

Absolvent: [anonimizat]

1

PLAN
TEMATIC:

formular
care
se
preia
de
la
secretariatul
departamentului,
se

completează
de
către

cadrul
didactic
îndrumător
si
se
înmânează
absolvent: [anonimizat]

2

Cuprins

1

.

Prezentarea Temei
5

1.1 Contextul proiectului
5

1.2 Idea
ș
i scopul lucrării
6

1.3 Structura lucrării
6

1.4 Actualizarea lucrării în cadrul unui concurs de inova
ț
ii
6

2. Considera
ț
ii teoretice
8

2.1 Aplica
ț
ia server
8

2.1.1 Medii de dezvoltare folosite
9

2.1.1.1 Visual Studio
9

2.1.2 Proiectarea bazei de date rela
ț
ională
9

2.1.2.1 Normalizarea bazei de date
10

2.1.3 Microsoft SQL Server
13

2.1.3.1 Entity Framework
13

2.1.3.2 Entity Framework Core
14

2.1.3.3 Entity Framework Code-First
15

2.1.4 ASP .NET Core Web API
16

2.1.4.1 Componentele .Net Framework
16

2.1.4.2 Atributele rutelor
18

2.1.5 Limbajul de programare C#
19

2.1.6.1 Programarea orientată pe obiect
20

2.2 Aplica
ț
ia client
22

2.2.1 Framework-uri
22

2.2.2 Mediul de dezvoltare
23

2.2.3 Angular Framework
23

2.3.1.1 Structura Angular
24

2.3.1.2 Componentele Angular
26

2.3.1.3 Injec
ț
ia de dependen
ț
ă în Angular
28

2.3.1.4 Limbajele folosite în Angular
28

2.3 Problema alocării de resurse
30

2.3.1 Comportamentul strategic atunci când alocăm bunuri indivizibile secven
ț
ial
31

2.3.1.1 Comportamentul strategic
32

2.3.2 Algoritmi implementa
ț
i
34

2.3.2.1 Adjusted Winner
34

2.3.2.2 Descending Demand
35

2.3.2 Utilitatea algoritmului Adjusted Winner
35

3. Descrierea formală a aplica
ț
iei
39

3.1 Arhitectura aplica
ț
iei
39

3.1.1 Arhitectura aplica
ț
iei server
40

3

3.1.2 Func
ț
ionalit ate
41

3.2 Scenarii de utilizare
54

4. Descrierea aplica
ț
iei
56

4.1 Structura aplica
ț
iei server
56

4.1.1 Metoda de alocare a modelelor
56

4.1.2 Algoritmii implementa
ț
i
58

4.1.2.1 Adjusted Winner
59

4.1.2.2 Descending Demand
64

4.1.3 Baza de date
68

4.2 Descrierea aplica
ț
iei web
70

4.2.1 Implementarea aplica
ț
iei client
77

5. Concluzii
ș
i dezvoltăr i ulterioare
84

5.1 Concluzii
84

5.1 Compara
ț
ii între algoritmi
84

5.1 Dezvoltări ulterioare
85

Abrevieri
86

Figuri
87

Bibliografie
89

4

1.
Prezentarea Temei

1.1 Contextul proiectului

În
prezent
numărul
creatorilor
de
design
vestimentar
este
în
continuă
cre
ș
tere,
ceea
ce

înseamnă

tot
mai
mul
ț
i
designeri
î
ș
i
doresc

î
ș
i
prezinte
colec
ț
iile
pe
o
scenă,
la
festivale

de
modă.
În
cadrul
unui
eveniment
de
prezentare,
fiecare
designer
dore
ș
te
manechinele

potrivite,
care
se
încadrează
în
standardelor
ș
i
cerin
ț
elor
lui,
astfel
încât
crea
ț
ia

iasă
în

eviden
ț
ă cât mai bine.

Săptămâna
modei
reprezintă
un
festival
de
modă,
în
care
se
desfă
ș
oară
un
ș
ir
de

evenimente
de-a
lungul
a
aproximativ
7
zile,
la
care
mai
mul
ț
i
designeri
de
modă
î
ș
i
prezintă

colec
ț
iile.
În
cadrul
festivalului,
manechinele
sunt
selectate
si
prezentate
designerilor
pentru

a-
ș
i
alege
preferatele.
Într-o
zi
pot
avea
loc
mai
multe
prezentări,
iar
un
manechin,
din
cauza

timpului
restrâns,
va
putea
fi
disponibil
doar
pentru
un
anumit
număr
limitat
de
prezentări
în

ziua
respectivă.
Un
manechin
poate
fi
ales
ca
preferat
de
mai
mul
ț
i
designeri
care
î
ș
i
prezintă

colec
ț
iile
în
aceea
ș
i
zi.
În
acest
caz,
repartizarea
acestuia
este
necesară

se
facă
într-un
mod

cât mai corect.

În
cadrul
organizării,
dezavantajul
major
al
acestor
festivale
îl
reprezintă
distribuirea

manechinelor.
Un
prim
efect
îl
reprezintă
crearea
unui
dezechilibru
în
alegerea
manechinelor

preferate
de
către
designeri.
Acestora
li
se
repartizează
manechine
în
func
ț
ie
de
alegerile

unuia
dintre
manageri,
rezultând
o
repartizare
haotică.
Un
al
doilea
efect,
sugerat
de
acest

aspect,
este
dat
de
instabilitatea
programului
manechinelor,
ajungându-se
deseori
la
situa
ț
ii
în

care
acestea
află
in
ziua
evenimentului
dacă
urmează

prezinte
moda
sau
nu,
sau
chiar
sa
fie

mult prea aglomerate în program
ș
i să se întârzie cu începerea evenimentelor.

Bazat
pe
dezavantajele
men
ț
ionate,
în
următoarea
lucrare
de
licen
ț
ă,
se
va
încerca

propunerea
ș
i
implement area
unui
nou
sistem
de
organizare
festivalelor
de
modă,
care
are
ca

scop
repartizarea
manechinelor
în
func
ț
ie
de
preferin
ț
ele
designerilor,
într-un
mod
cât
mai

corect.

5

1.2 Idea
ș
i scopul lucrării

Ideea
lucrării
constă
în
crearea
unui
sistem
de
alocare
a
resurselor
umane,
bazate
pe

anumite
criterii
de
selec
ț
ie,
într-un
mod
cat
mai
corect
ș
i
egal.
Astfel,
designerilor
li
se
vor

aloca
manechinele
dorite.
Pe
lângă
acest
aspect,
sistemul
simplifică
munca
managerului,

repartizarea
făcându-se
automat
pe
loc.
Un
alt
beneficiu
în
cadrul
acestei
lucrări,
îl
reprezintă

rezultarea
unui
program
bine
stabilit
pentru
manechinele,
de-a
lungul
întregului
festival.

Acestea
fiind
în
ș
tiin
ț
ate
cu
privire
la
programul
de
muncă,
ș
tiind
exact
când
unde
ș
i
când

trebuie să meargă.

1.3 Structura lucrării

Această
lucrare
este
organizată
în
patru
capitole,
primul
este
introductiv
ș
i
con
ț
ine

contextul, ideea
ș
i scopul lucrării.

Acesta
este
urmat
de
capitolul
al
doilea,
capitol
ce
con
ț
ine
planul
tematic
alcătuit
din

programele
folosite
în
cadrul
aplica
ț
iei,
limbajul
de
programare
folosit,
teorie
legată
alocarea

modelelor în cadrul festivalelor de modă
ș
i o prezentare detaliată a sistemului proiectului.

În
capitolul
al
treilea,
este
prezentată
arhitectura
aplica
ț
iei
cu
ajutorul
schemelor

logice, a diagramelor
ș
i o prezentare a bazei de date folosite.

Capitolul
al
patrulea
este
format
din
explicarea
codului
în
detaliu
ș
i
prezentarea

acestuia cu ajutorul capturilor de ecran.

1.4 Actualizarea lucrării în cadrul unui concurs de inova
ț
ii

Această
lucrare
a
fost
prezentată
în
cadrul
concursului
Innovation
Labs
de
la
Sibiu,

care
se
desfă
ș
oară
anual.
Actualizarea
lucrării
a
constat
într-o
platformă
de
afi
ș
are
a

modelelor
pentru
a
fi
găsite
de
poten
ț
ialii
investitori,
cum
ar
fi
diverse
firme
de
publicitate,

festivale
de
modă,
designeri
etc.
Pe
lângă
acest
aspect,
platforma
oferă
un
ajutor
pentru

organizarea
repartizării
modelelor
în
cadrul
festivalelor
de
modă,
subiectul
principal
al

licen
ț
ei.
Pentru
a
conving e
juriul
din
cadrul
concursului

această
aplica
ț
ie
este
le
foarte
utilă

6

festivalurilor,
am
discutat
cu
câteva
dintre
ele.
Acestea
s-au
arătat
foarte
interesate
iar
unul

dintre ele dore
ș
te să teste ze aplica
ț
ia chiar la următorul evenimen t.

7

2. Considera
ț
ii teoretice

Termenii
de
aplica
ț
ie
client
(front-end)
ș
i
aplica
ț
ie
server
(back-end)
se
referă
la

separarea
preocupărilor
dintre
front-end
ș
i
stratul
de
acces
la
date
al
unei
păr
ț
i
de
software.
În

modelul
client-server,
clientul
este
considerat,
de
obicei,
front-end
ș
i
serverul
este
de
obicei

considerat
ca
fiind
back-end.
Codul
care
este
scris
de
programatorul
de
front-end
rulează
în

browser-ul
utilizatorului,
în
timp
ce
codul
unui
dezvoltator
de
back-end
rulează
pe
serverul

web.
De
exemplu,
dezvoltatorul
din
spate
ar
putea
fi
un
inginer
care
proiectează
ș
i
creează

sistemele
care
realizează
o
activitate
urbană
(electricitate,
apa
etc.),
în
timp
ce
dezvoltatorul

de
front-end
este
cel
care
se
asigură
în
mod
direct,
prin
interac
ț
iunea
cu
sistemele
realizate

acestea sunt conectate corespunzător, astfel încât locuitorii să ducă o via
ț
ă decentă.

Figura 1. Aplica
ț
ie server-client

2.1 Aplica
ț
ia server

Aplica
ț
ia
server
este
codul
care
rulează
pe
server,
care
prime
ș
te
cereri
de
la
clien
ț
i
ș
i

con
ț
ine
logica
pentru
a
trimite
datele
corespunzătoare
către
client.
Acesta
reprezintă
toată

tehnologia
necesară
procesării
cererii
de
intrare
ș
i
generării
trimiterii
răspunsului
către
client.

Acesta include trei păr
ț
i majore:

8


Serverul

un
program
pe
calculator
sau
un
dispozitiv,
care
oferă
func
ț
ionalitate
pentru

alte programe sau dispozitive, numite ”clien
ț
i„


Aplica
ț
ia

aceasta
este
aplica
ț
ia
care
rulează
pe
server,
care
ascultă
cererile,

prelucrează informa
ț
ii din baza de date
ș
i trimite un răspu ns.


Baza de date – utilizată pentru organizarea
ș
i persisten
ț
a datelor. [1]

2.1.1 Medii de dezvoltare folosite

Mediile
de
dezvoltare
folosite
pentru
partea
de
back-end
sunt:
Visual
Studio
ș
i

Microsoft SQL Server

ș
i vor fi prezentate în continuare.

2.1.1.1 Visual Studio

Visual
Studio
este
un
IDE
(Integrated
Development
Enviroment)
care
se
poate
ob
ț
ine

gratuit,
open-source
care
poate
rula
oriunde.
Acesta
oferă
suport
pentru
limbajul
C#
folosit
în

aplica
ț
ie
si
care
urmea ză

fie
descris
mai
jos.
Este
un
software
care
consolidează

instrumentele
de
bază
necesare
atât
pentru
scrierea
cât
ș
i
pentru
testarea
software-ului.
Unul

dintre
marile
beneficii
ale
acestuia
este

îmbunătă
ț
e
ș
te
produ ctivitatea
dezvoltatorilor
de

software, datorită configura
ț
iei rapide a instrumentelor.

2.1.2 Proiectarea bazei de date rela
ț
ională

Baza
de
date
rela
ț
ională
a
fost
propusă
pe
la
sfâr
ș
itul
anului
1970
de
către
Edgar

Codd, devenind mai apoi modelul de bază de date dominantă pentru aplica
ț
iile comerciale.

Organizarea
datelor
într-o
bază
de
date
rela
ț
ională
se
face
prin
tabele
(sau
rela
ț
ii).

Astfel,
un
tabel
este
alcătuit
din
rânduri
ș
i
coloane.
Un
rând
reprezintă
o
înregistrare
ș
i
o

coloană
se
mai
nume
ș
te
un
câmp
(sau
atribut).
Putem
asimila
un
tabel
de
bază
de
date
cu
o

foaie
de
calcul.
Pentru

rela
ț
iile
care
pot
fi
create
între
tabele
permit
o
baza
de
date

rela
ț
ională,
în
cazul
unei
cantită
ț
i
mari
de
date,
aceasta
le
stochează
eficient
ș
i
facilitează

preluarea datelor selectate.

Limbajul
care
a
fost
dezvoltat
pentru
a
lucra
cu
bazele
de
date
rela
ț
ionale
poartă

numele de SQL (Structured Query Language).

9

2.1.2.1 Normalizarea bazei de date

Caracteristica
principală
a
bazei
de
date
rela
ț
ionale
constă
în
rela
ț
ia
care
poate
fi

definită
între
tabele.
Identificarea
rela
ț
iilor
dintre
tabele
reprezintă
parametrul
cel
mai

important în proiectarea unei baze de date rela
ț
ionale. Tipurile de rela
ț
ii includ:


One-to-many (unu-la-mul
ț
i)


Many-to-many (multi-la-mul
ț
i)


One-to-one (unu-la-unu)


One-to-many (unu-la-mul
ț
i)

Într-o
bază
de
date
de
„listă
evenimente”,
un
designer
î
ș
i
poate
prezenta
colec
ț
ia
de

haine
de
la
zero
sau
la
mai
multe
evenimente,
în
timp
ce
un
eveniment
este
prezentat
de
un
(
ș
i

numai
unul)
designer.
Într-o
bază
de
date
„festival”,
un
manager
gestionează
zero
sau
mai

mul
ț
i
angaja
ț
i,
în
timp
ce
un
angajat
este
gestionat
de
un
(
ș
i
numai
unul)
manager.
Într-o
bază

de
date
„vânzări
de
produse”,
mai
multe
comenzi
pot
fi
plasate
de
un
client,
în
timp
ce
un

ordin
este
plasat
de
un
anumit
client.
Tipul
acestei
rela
ț
ii
este
cunoscut
sub
numele
de

one-to-many (unu-la-mul
ț
i).

One-to many

Rela
ț
iile
unu-la-m ul
ț
i
nu
pot
fi
reprezentate
doar
într-u n
singur
tabel.
De
exemplu,

într-o
bază
de
date
de
„listă
evenimente”,
putem
începe
cu
un
tabel
numit
Designer,
care

stochează
informa
ț
ii
despre
designeri
(cum
ar
fi
numele,
telefon
ș
i
e-mail).
Pentru
a
stoca

evenimentele
care
urmează
sa
aibe
loc
ale
designerilor,
am
putem
crea
coloane
eveniment1,

eveniment2.
eveniment3,
dar
intervine
o
problemă
cu
privire
la
numărul
mare
de
coloane
care

urmează

fie
creat.
Pe
de
altă
parte,
dacă
vom
începe
cu
un
tabel
numit
evenimente,
care

stochează
informa
ț
ii
despre
un
eveniment
(dataEvent,
timeEvent
ș
i
locationEvent),
am
putea

crea
coloane
suplimentare
pentru
a
stoca
informa
ț
ii
despre
(unul)
desginer
(cum
ar
fi
numele.

telefon
ș
i
e-mail).
Cu
toate
acestea,
din
moment
ce
un
designer
poate
avea
mai
multe

evenimente, datele sale vor fi duplicate în mai multe rânduri în tabelul de evenimente.

În
scopul
sprijinirii
rela
ț
iei
unu-la-mul
ț
i,
avem
nevoie
de
a
proiecta
două
tabele:
un

tabel
Events
pentru
a
stoca
informa
ț
ii
despre
evenimente,
cu
eventID
cheie
primară,
ș
i
un

tabel
Designers,
pentru
a
stoca
informa
ț
ii
despre
designeri
cu
designerID
ca
ș
i
cheie
primară.

10

Putem
crea
apoi
rela
ț
ia
unu-la-mul
ț
i
prin
stocarea
cheii
primare
a
tabelului
Designer

(designerID) în tabelul de evenimente, a
ș
a cum este ilustrat mai jos.

Figura 2. Exemplu de legătură unu la mul
ț
i

Coloana
desigerID
în
tabelul
din
events
este
cunoscut
ca
fiind
o
cheie
străină.
Pentru

un
tabel
copil,
o
cheie
externă
este
o
cheie
primară
a
unui
tabel
părinte,
folosit
pentru
a
face

referire la tabelul părinte.

Many-to-many

Într-o
bază
de
date
„vânzări
de
căr
ț
i”,
comanda
unui
singur
client
con
ț
ine
unu
sau
mai

multe
căr
ț
i,
iar
o
carte
poate

apară
în
mai
multe
comenzi.
Într-o
bază
de
date
numită

„librărie”,
o
carte
este
scrisă
de
unul
sau
mai
mul
ț
i
autori,
în
timp
ce
un
autor
poate

scrie

mai
multe
căr
ț
i.
Tipul
acestei
rela
ț
ii
este
cunoscută
ca
fiind
dată
sub
numele
de

mul
ț
i-la-mul
ț
i.

În
continuare
voi
exemplifica
o
bază
de
date
„vânzări
de
căr
ț
i”.
Pentru
început
voi

crea
două
tabele:
căr
ț
i
ș
i
comenzi.
Tabelul
de
căr
ț
i
con
ț
ine
detalii
despre
căr
ț
i
(precum

numele,
descrierea
si
cantitatea
de
stoc)
cu
cheia
primară
„carteId”.
Tabelul
de
comenzi

urmează

con
ț
ină
de
asemenea
ordinele
clientului
(codul
clientului,
dataComenzii,

dataPrimirii
ș
i starea). În tabelul de căr
ț
i nu se pot stoca detalii de spre comandă.

În
scopul
sus
ț
inerii
rela
ț
iei
de
mul
ț
i-la-mul
ț
i,
avem
nevoie
de
a
crea
al
treilea
tabel

(cunoscut
ca
un
tabel
de
jonc
ț
iune),
sub
numele
de
„DetaliiComanda”,
în
cazul
în
care
fiecare

rând
sugerează
un
element
dintr-o
anumită
ordine.
Cheia
primară
din
tabelul

„DetaliiComanda”
este
formată
din
două
coloane:
comandaId
ș
i
carteId,
care
identifică
în

mod
unic
fiecare
rând.
Coloanele
„comandaId”
ș
i
„carteId”
din
tabelul
„DetaliiComanda”

11

sunt
folosite
ca
ș
i
referin
ț
ă
pentru
tabelele
Comenzi
ș
i
Căr
ț
i,
astfel,
acestea
sunt
cheile
străine

din tabelul „DetaliiComanda”.

Figura 3. Exemplu de legătură mul
ț
i-la-mul
ț
i

Această
rela
ț
ie
de
mul
ț
i-la-mul
ț
i
este,
mai
exact,
implementată
ca
fiind
două
rela
ț
ii

unu-la-mul
ț
i,
odată
cu
introducerea
tabelului
de
jonc
ț
iune.
Astfel,
o
comandă
con
ț
ine
mai

multe
elemente
în
„DetaliiComanda”.
O
carte
apare
în
mai
multe
tabeleDetaliiComandă.

Fiecare element din ComandaDetalii are specificat o singură carte.

One-to-One

Într-o
bază
de
date
„alocarea
modelelor”,
un
model
poate
avea
mai
multe
informa
ț
ii

suplimentare
op
ț
ionale,
cum
ar
fi
înăl
ț
imea
ș
i
culoarea
părului.
Men
ț
inerea
lor
în
interiorul

tabelului
de
modele
ar
rezulta
în
tabel
mai
multe
spa
ț
ii
goale.
Mai
mult,
aceste
date
mari
pot

degrada performan
ț
a baze i de date.

În
schimb,
putem
crea
un
alt
tabel
(căruia
îl
denumin
ModelDetails)
pentru
a
stoca

datele
op
ț
ionale.
O
înreg istrare
va
fi
creată
numai
pentru
acele
modele
cu
date
op
ț
ionale.

Celelalte
două
tabele,
Models
ș
i
ModelDetails,
sugerează
o
rela
ț
ie
unu-la-unu.
Aceasta

înseamnă

pentru
fiecare
rând
din
tabela
părinte,
există
cel
mult
un
rând
(posibil
zero)
în

tabelul de copii.

O
limitare
pe
care
o
pot
avea
unele
baze
de
date
este
reprezentată
de
numărul
de

coloane
redus
care
pot
fi
create
în
interiorul
unui
tabel.
În
acest
scop,
se
poate
folosi
o
rela
ț
ie

12

de
unu-la-unu
pentru
a
împăr
ț
i
datele
în
două
tabele.
Un
alt
avantaj
al
rela
ț
iei
de
unu-la-unu

este
dat
de
stocarea
anumitor
date
sensibile
într-un
tabel
securizat,
iar
cele
non-sensibile
în

tabelul principal.

Figura.4. Exemplu de legătură unu-la-unu

2.1.3 Microsoft SQL Server

Microsoft
SQL
Server
reprezintă
un
sistem
de
gestionare
a
bazei
de
date
rela
ț
ionale

[2].
Pentru
a
comunica
cu
baza
de
date,
se
folose
ș
te
limbajul
de
interogare
este
SQL

(pronun
ț
at
"ESS-que-el" ).
Acest
limbaj,
conform
ANSI
(American
National
Standards

Institute),
reprezintă
limbajul
standard
pentru
sistemele
de
management
de
baze
de
date

rela
ț
ionale.
Instruc
ț
iunile
SQL
sunt
întrebuin
ț
ate
pentru
a
executa
diverse
sarcini,
cum
ar
fi

actualizarea
sau
preluarea
unor
date
din
baza
de
date.
Câteva
dintre
sistemele
comune
de

management
de
baze
de
date
rela
ț
ionale
care
folosesc
SQL
sunt:
Microsoft
SQL
Server,

Oracle,
Access
etc.
De
ș
i
majoritatea
sistemelor
de
baze
de
date
folosesc
SQL,
un
număr
mare

dintre
ele
au,
de
asemenea,
propriile
extensii
proprietare
suplimentare,
care
sunt
în

majoritatea
cazurilor
utilizate
doar
pe
sistemul
lor.
Prin
urmare,
comenzile
SQL
standard:

„Select”,
„Insert”,
„Update”,
„Delete”,
„Create”
ș
i
„Drop”
pot
fi
folosite
pentru
a
realiza

aproape tot ceea ce este nevoie într-o bază de date.

2.1.3.1 Entity Framework

Entity
Framework
este
un
set
de
tehnologii
care
sprijină
dezvoltarea
de
aplica
ț
ii

software
orientate
pe
date.
Acest
framework
permite
dezvoltatorilor

lucreze
cu
date
sub

formă
de
obiecte
ș
i
propr ietă
ț
i
specifice
unui
domeniu,
cum
ar
fi
clien
ț
ii
ș
i
adresele
acestora,

13

fără
a
fi
nevoie

se
preocupe
cu
tabelele
bazei
de
date
ș
i
de
modul
în
care
sunt
stocate

datele.
Cu
Entity
Framework,
dezvoltatorii
pot
lucra
la
un
nivel
mai
ridicat
de
abstractizare

când
se
ocupă
de
date
ș
i
pot
crea
ș
i
men
ț
ine,
în
acela
ș
i
timp,
aplica
ț
ii
orientate
spre
date
cu

mai pu
ț
in cod decât în ap lica
ț
iile tradi
ț
ionale [3].

Acest
framework
este
un
ORM
(Object
Relational
Mapper),
reducând
astfel

impedan
ț
a
nepotrivită
între
lumea
orientată
pe
obiecte
de
dezvoltatorii
.NET
framework
ș
i

lumea
bazelor
de
date
rela
ț
ionale.
Entity
Framework
permite
inclusiv
dezvoltatorilor

interac
ț
ioneze
direct
cu
modelul
conceptual
al
unei
aplica
ț
ii,
folosind
tehnici
orientate
pe

obiecte familiare.

În

Entity
Framework
se
poate
lucra
cu
datele
aflate
sub
formă
de
obiecte
ș
i
proprietă
ț
i

specifice
unui
anumit
domeniu,
precum
clien
ț
ii
ș
i
adresele
acestora.
Avantajul
acestei

men
ț
ionări
este
dat
de
faptul

toate
acestea
se
realizează
fără
a
necesita
preocuparea
cu

tabelele
bazei
de
date,
care
stau
la
fundamentul
coloanelor
ș
i
în
modul
în
care
sunt
stocate

datele.

Framework-ul
folose
ș
te
componenta
de
mapare
pentru
a
transforma
opera
ț
iunile

împotriva
obiectelor,
precum:
crearea,
citirea,
actualizarea
ș
i
ș
tergerea

în
opera
ț
iuni

echivalente în baza de date a entită
ț
ii.

2.1.3.2 Entity Framework Core

Microsoft
a
primit
o
mul
ț
ime
de
critici
din
partea
comunită
ț
ii
de
dezvoltare
pentru

programele
Windows
ș
i
a
instrumentelor
lor.
Microsoft,
aflându-se
sub
conducerea

CEO-ului
(director
general)
Satya
Nadella,
a
făcut
un
pas
mare
în
acest
sens
ș
i
a
extins

instrumentele
ș
i framewo rk-ul lor la cross-platform
ș
i open source.

La
început
a
fost
numit
„Entity
Framework
7“,
iar
apoi
i
s-a
schimbat
numele
în

„Entity

Framework
Core“,
deoarece
această
ultimă
versiune
nu
este
un
accesoriu
pe
Entity

Framework
original,
ci
mai
degrabă
o
rescriere
completă.
Astfel,
setul
de
caracteristici
pentru

EF
Core
este
foarte
diferit
de
cel
al
EF6,
iar
utilizatorii
existen
ț
i
EF
trebuie

fie
con
ș
tien
ț
i

de faptul că trecerea de la una la alta nu este o sarcină mică într-un proiect existent [4].

EF
Core
are
multe
întrebuin
ț
ări
fa
ț
ă
de
EF6.
Vine
cu
o
interfa
ț
ă
îmbunătă
ț
ită
a
liniei

de
comandă,
u
ș
urând
munca
dezvoltatorilor.
Beneficiul
suprem
pentru
dezvoltatori
rămâne

abilitatea de a utiliza framework-ul în mediile non-Windows.

14

Cu
toate
acestea,
EF
Core
are
câte
lipsuri
în
vederea
caracteristicilor
pe
care
le

prevede
EF6.
Astfel,
pentru
a
umple
golurile
sunt
eliberate
actualizările.
Între
timp,
aceste

absen
ț
e
vor
putea
duce
la
frustrare.
Din
acest
motiv,
aceste
considerente
trebuie
luate
în

considerare
înainte
de
a
adopta
EF
Core
pentru
proiect.
Unele
dintre
caracteristicile
care

lipsesc
sunt
următoarele:
rela
ț
iile
de
many-to-many,
fără
o
entitate
„JOIN”
ș
i
încărcarea

înceată (sau lazy loading) .

2.1.3.3 Entity Framework Code-First

No
ț
iunea
de
Entity
Framework
Code-First
a
fost
introdusă
de
Entity
Framework

versiunea
4.1
Code-First.
Această
abordare
este
utilă
în
Domain-Driven
Design
(

o
abordare
a

dezvoltării
de
software
pentru
nevoi
complexe
prin
conectarea
implementării
la
un
model
în

evolu
ț
ie
[5]

).
În
continua re,
prin
acostarea
Code-First,
ne
concentrăm
pe
domeniul
aplica
ț
ie
ș
i

începem

creăm
clase
pentru
domeniul
nostru
de
entită
ț
i.
Cu
ajutorul
lui
Database-First
am

crea clase care ar trebui să se potrivească cu design-ul bazei de date [6].

Figura 5. Abordarea Code-First

După
cum
se
observă
în
schema
de
mai
sus,
care
ilustrează
abordarea
Code-First,

API-ul
de
Entity
Framework
va
crea
baza
de
date
bazată
pe
configura
ț
ia
claselor
entită
ț
ilor.

A
ș
adar,
vom
scrie
cod
în
C#
prima
dată,
iar
apoi
Entity
Framework
va
genera
baza
de
date

din codul scris de către noi.

15

2.1.4 ASP .NET Core Web API

ASP
.NET
este
o
platformă
de
dezvoltare
web,
care
beneficiază
de
un
model
de

programare,
o
infrastructură
software
care
cuprinde
diverse
servicii
necesare
pentru
a
construi

aplica
ț
ii web robuste pen tru PC-uri, precum
ș
i pentru dispozitive mobile [7].

Această
platformă
face
parte
din
platforma
Microsoft
.Net
ASP
.NET
ș
i
este

func
ț
ională
pe
partea
de
sus
a
protocolului
HTTP,
utilizând
atât
comenzile
cât
ș
i
politicile

HTTP pentru a stabili o comunicare
ș
i cooperare bilaterală a browser-ului la server.

Scopul
utilizării
platformei
este
pentru
a
produce
aplica
ț
ii
web
interactive,
bazate
pe

date
de
internet.
Aceasta
consistă
într-un
număr
mare
de
controale,
cum
ar
fi
casete
de
text,

butoane
ș
i
etichete
pentru
asamblare,
configurare
ș
i
codul
de
manipulare
pentru
pagini

HTML.
Browserul
trimite
un
formular,
de
pe
web,
la
serverul
web,
iar
serverul
returnează
o

pagină de marcare sau pagină HTML completă ca răspuns.

Activită
ț
ile
utiliza torului
pe
partea
de
client
sunt
transmise
la
server
pentru
a
putea
fi

procesate. Ac
ț
iunile clien tului sunt procesate de server
ș
i urmează declan
ș
area reac
ț
iilor.

Tehnologia
ASP
.NET
func
ț
ionează
pe
.NET
Framework,
care
cuprinde
toate

fun
ț
ionalită
ț
ile
în
materie
de
web.
.NET
Framework
este
conceput
dintr-o
organizare

orientare-obiect.
O
aplica
ț
ie
web
ASP
.NET
este
o
alcătuită
din
pagini.
Astfel,
atunci
când

utilizatorul
solicită
o
pagină
ASP
.NET,
deleagă
IIS
(Internet
Information
Services)
pentru

procesarea paginii în sistemul ASP .NET.

2.1.4.1 Componentele .Net Framework

Common Language Runtime

(CLR)

CLR
se
efectuează
de:
managementul
memorie,
manipularea
excep
ț
iilor,
depanare,

verificarea
de
securitate,
execu
ț
ia
fir,
executarea
de
cod,
codul
de
siguran
ț
ă,
verificare
ș
i

compilare.
Codul
care
este
direct
gestionat
de
CLR,
poartă
numele
de
„cod
gestionat”.
Atunci

când
codul
gestionat
este
compilat,
compilatorul
urmăre
ș
te
convertirea
codului
sursă
într-un

cod
de
CPU,
independent
de
limba
intermediară
(IL).
Codul
IL
urmează
a
fi
compilat
de
un

compilator JIT (Just In Time) în cod nativ, specific CPU-ului.

Class Library .Net Framework

16

Class
Library
.Net
Framework
con
ț
ine
o
bibliotecă
foarte
mare
de
tipuri
reutilizabile:

structuri, clase, interfe
ț
e
ș
i anumite tipuri colective.

Common Language Specification

(Specifica
ț
ii Limba Comună)

Specifica
ț
iile
.NET
pentru
acceptarea
ș
i
integrarea
limbi i
sunt
cuprinse
de
Common

Language Specification.

Common Type System

(Sistemul de tip comun)

În
timpul
rulării,
sistemul
de
tip
comun
oferă
instruc
ț
iuni
despre
declararea,
utilizarea

ș
i gestionarea tipurilor
ș
i despre comunicarea în limba transversal ă.

Metadate
ș
i Ansamblur i

O
informa
ț
ie
binară
care
caracterizează
programul
ș
i
care
poate
fi
stocată
într-un
fi
ș
ier

executabil
portabil
sau
în
memorie,
poartă
numele
de
Metadată.
Ansamblul
reprezintă
o

unitate
logică
care
rezidă
din
manifestul
de
asamblare,
tipul
de
metadate,
codul
IL
ș
i
un
set
de

resurse, de exemplu, fi
ș
ierele de imagine.

LINQ

Folosind
o
sintaxă
care
este
similară
cu
limbajul
de
interogare
SQL,
LINQ
acordă

posibilită
ț
i de interogare a datelor din .NET.

Pentru
a
permite
consumatorilor
să:
creeze,
citească,
actualizeze
ș
i

ș
teargă
ordinele,

avem
nevoie
de
a
crea
un
RESTful
Web
API.
Această
ac
ț
iune
se
realizează
prin

implementarea
opera
ț
iilor
CRUD
(

create
=
creare,
read
=
ș
tergere,
update
=
actualizare
ș
i

delete =
ș
tergere

).

17

Figura 6. Opera
ț
iile CRUD

2.1.4.2 Atributele rutelor

ASP.NET
Core
oferă
un
atribut
puternic
rutelor
[8].
Astfel,
se
poate
defini
o
rută
de

nivel
superior
la
clasa
controller,
prin
care
se
reiese
un
traseu
comun
în
care
ac
ț
iunile
se
pot

extinde asupra lui.

Atributul
Route
este
reprezentat
printr-un
ș
ablon
„api
/
[Controller]“.
Conven
ț
ia

specială
„[Controller]“
ac
ț
ionează
ca
un
substituent
pentru
controler
în
context.
Îndreptând

aten
ț
ia
asupra
HttpGet,
se
observă

oferim
un
argument
ș
ablon
de
„{id}“.
Astfel
reiese
un

traseu
HTTP
Get
care
se
aseamănă
cu
„api/
comenzi/
1”
(în
cazul
în
care
id-ul
este
o

variabilă).

HTTP GET

– Cerere (Request)

În
colec
ț
ia
noastr ă
de
comenzi,
aproape
fiecare
comandă
are
un
câte
un
identificator

unic. Ac
ț
iunea care se oc upă de această cerere, poate fi scrisă astfel:

HttpGet("api/models/{id}") // api/models/8

Acest
atribuit
va
pregăti
cadrul
ASP
.NET
Core
pentru
tratarea
ac
ț
iunii
ca
un
handler

al
verbului
HTTP
GET
ș
i

se
ocupe
de
rutare.
În
continuare,
noi
vom
furniza
un
ș
ablon,
ca

endpoint
de
argument
pentru
atribut.
Pentru
traseu,
ș
ablonul
oferă
cadrul
care
se
va
utiliza

pentru
a
se
potrivi
cu
cererile
primite.
Valoarea
sec
ț
iunii
{id}
din
cadrul
acestui
ș
ablon,
va

corespunde por
ț
iunii trase ului, care este parametrul „id”.

HTTP POST

– Cerere (Request)

Un HTTP Post este o cerere de a crea o resursă. Ac
ț
iunea poate fi scrisă astfel:

HttpPost("api/models")

O
diferen
ț
ă
rapid
vizibilă
fa
ț
ă
de
Get,
este

la
ac
ț
iunea
Post
nu
avem
nevoie
de
un

„{id}”
în
ș
ablonul
nostru ,
a
ș
a
cum
ni
se

întregul
obiect
coman dă
prin
corpul
cererii
HTTP

Post.
O
altă
deosebire
este
dată
de
cuvinte
cheie
care
trebuiesc
folosite
în
cadrul
programului:

async pentru a permite utilizarea await.

HTTP PUT

– Cerere (Request)

18

HTTP
Put
reprezintă
o
solicitare
pentru
a
actualiza
o
resursă.
Aceste
verb
are
calitatea

de
a
fi
idempotent.
Aceasta
înseamnă
că,
în
cazul
în
care
are
loc
o
cerere
HTTP
Put,
orice

cerere
care
urmează
HTTP
Put
cu
aceea
ș
i
sarcină
utilă,
ar
avea
ca
rezultat
acela
ș
i
răspuns.

Altfel
spus,
mai
multe
cereri
HTTP
Put
egale,
sunt
nedăunătoare,
iar
resursa
este
afectată

numai pentru prima solicitare.

Acest
verb
seamănă
foarte
mult
cu
verbul
HTTP
Put,
în
care
atributele
ASP
.NET

Core sunt împreună perechi. Ac
ț
iunea este scrisă astfel:

HttpPut("api/orders/{id}")

HTTP DELETE

– Cerere (Request)

Ultima
opera
ț
ie
din
CRUD
este
opera
ț
ia
de
ș
tergere,
iar
aceasta
este
expusă
prin

ac
ț
iunea
care
se
ocupă
de
cererea
HTTP
Delete.
În
urma
acestei
ac
ț
iuni,
rezultă
ș
tergerea

înregistrarea de la ID-ul dat. Ac
ț
iunea este scrisă astfel:

HttpDelete("api/models/{id}")

2.1.5 Limbajul de programare C#

Limbajul
C#
este
un
limbaj
de
programare
creat
de
Microsoft
la
începutul
anilor
2000

ș
i
care
a
apărut
pentru
îndeplinirea
cerin
ț
ele
lumii
moderne,
interconectate.
Acest
limbaj

derivă
din
C
ș
i
C++,
(figura
2)
de
unde
putem
spune

este
un
limbaj
de
programare
simplu

ș
i
orientat
pe
obiect.
C#
utilizează
arhitectura
.NET
ce
conferă
o
portabilitate
mare
a
codului

ș
i
permite
programarea
în
limbaj
mixt.
Ca
ș
i
inova
ț
ii,
permite
o
progresare
a
componentelor

software,
foarte
necesare
de
pildă,
în
medii
distribuite.
Astfel,
acest
limbaj
se
poate

caracteriza ca fiind
ș
i orie ntat pe componente, nu numai orientat pe obiect.

Momentan,
C#
reprezintă
una
dintre
cele
mai
populare
limbaje
de
programare.
Este

utilizat de milioane de dezvoltatori din întreaga lume. [9]

19

Figura 7: Arborele genealogic C#

2.1.6.1 Programarea orientată pe obiect

Programarea
orientată
pe
obiecte
este
succesorul
programării
procedurale

(structurale).
Procedurile
de
programare
descriu
programele
ca
fiind
grupuri
de
unită
ț
i
de
cod

reutilizabile
(proceduri)
care
definesc
parametrii
de
intrare
ș
i
ie
ș
ire.
Programele
procedurale

constau în proceduri care se invocă reciproc.

Problema
cu
programarea
procedurală
este

reutilizarea
codului
este
grea
ș
i
limitată.

Nu
există
o
modalitate
u
ș
oară
de
a
lucra
cu
structuri
de
date
abstracte
cu
implementări

diferite, precum în programarea orientată pe obiect.

Abordarea
orientată
spre
obiecte
se
bazează
pe
paradigma

fiecare
program

func
ț
ionează
cu
date
care
descriu
entită
ț
i
(obiecte
sau
evenimen te).
Avantajele
principale
ș
i

obiective
ale
OOP
sunt
de
a
mării
complexitatea
ș
i
viteza
software-ului,
pentru
a
putea
fi

dezvoltat
mai
u
ș
or.
OOP
permite
reutilizarea
mai
u
ș
oară
a
codului
prin
aplicarea
unui
set
de

reguli. Aceasta sunt: mo
ș
tenirea, încapsularea, abstractizarea
ș
i polimorfismul.

Mo
ș
tenirea
este
principiul
fundamental
al
OOP-ului.
Prin
mo
ș
tenire,
se
în
ț
elege

crearea
unei
clase
dintr-o
clasă
existentă
deja,
astfel
încât
noua
clasă
va
fi
o
versiune

specializată
a
clasei
existente.
Toate
caracteristicile
clasei
de
bază
vor
fi
dobândite
de
clasa

derivată.
Se
poate
crea
o
ierarhie
de
clase,
în
care
o
clasă
derivată
poate
mo
ș
teni
o
clasă
de

bază, din care să derive alte clase. Acest principiu acordă eficien
ț
ă prin reutilizarea codului.

Încapsularea
îmbină
codul
ș
i
datele
pe
care
acesta
le
manipulează,
într-un
singur

obiect.
Aceasta
permite
programatorului
implementarea
abstractizării
dintr-un
program,
prin

intermediul specificatorilor.

20

Abstractizarea
detonă
caracteristicile
esen
ț
iale
ș
i
necesare
ale
unui
obiect
care
îl

deosebe
ș
te
de
toate
celelalte
tipuri
de
obiect
ș
i
permite
afi
ș
area
acestora
în
afara
clasei.

Accesarea acestora poate fi publică, privată sau protected.

Polimorfismul
permite
tratarea
obiectelor
unei
clase
derivate
ca
obiecte
ale
clasei
sale

de bază. Acesta reprezintă o capacitate de a redefini metode pentru clasele derivate.

Principiile OOD

(object orientated design)

Programarea
structurală
ș
i
programarea
orientată
pe
obiect
au
avut
un
rol
foarte

important
în
dezvoltarea
metodologiilor
de
a
scrie
cod
cât
mai
eficient
posibil.
Totu
ș
i,
a

devenit
dificilă
scrierea
unui
program
care
nu
are
aspectul
exterior
atât
al
programării

structurale
cât
ș
i
al
programării
orientate
pe
obiect.
În
acest
scop,
s-a
dezvoltat
designul

orientat
pe
obiect
care
reprezintă
un
proces
de
planificare
a
unui
sistem
de
obiecte,

interac
ț
ionând
în
scopul
rezolvării
unei
probleme
software.
Este
o
abordare
a
designe-ului

software.
Cele
5
principii
OOD-ului
sunt:
principiul
responsabilită
ț
ii
unice,
principiul

deschis-închis,
principiul
de
substitu
ț
ie
al
lui
Liskov,
principiul
de
segregare
a
interfe
ț
ei
ș
i

principiul
inversării
dependen
ț
ei.
Aceste
principii
mai
sunt
denumite
ca
fiind
ș
i
principiile

SOLID datorită denumirii fiecărui principiu care urmează să fie descris mai jos.

Primul
principiu
(in
engleză
The
Single
Responsibility
Principle)
spune

o
clasă
ar

trebui
sa
aibă
doar
un
singur
motiv
pentru
care

se
schimbe.
Dacă
o
clasă
are
mai
multe

responsabilită
ț
i,
atunci
responsabilită
ț
ile
devin
cuplate.
Schimbările
la
o
singură

responsabilitate pot afecta sau inhiba capacitatea clasei de a se întâlni cu ceilal
ț
i.

Al
2

lea
principiu
(The
Open
Closed
Principle)
sugerează

o
clasă
trebuie

fie

deschisă
pentru
extindere
ș
i
închisă
pentru
modificări.
De
exemplu,
atunci
când
se
schimbă

cerin
ț
ele
este
indicat

extindem
comportamentul
acestora
prin
adăugarea
unui
cod,
nu
prin

schimbarea codului vechi care deja func
ț
ionează.

Principiul
de
substitu
ț
ie
al
lui
Liskov
(The
Liskov
Sustitution
Principle)
este
introdus

de
Barbara
Liskov
în
1987.
Acesta
reprezintă
faptul

func
ț
iile
care
utilizează
pointeri
sau

referin
ț
e
la
clasele
de
bază,
trebuie

utilizeze
obiecte
din
clasele
derivate,
iar
clasele
care
au

fost mo
ș
tenite să nu cuno ască acest lucru.

Principiul
4
de
segregare
al
interfe
ț
ei
(The
Interface
Segretation
Principle)
recomandă

scrierea
a
cât
mai
multor
interfe
ț
e
cu
cu
granula
ț
ie
fină,
care
sunt
specifice
clientului.
Aceasta

21

afirmă

modulele
care
încapsulează
politica
de
nivel
înalt
nu
ar
trebui

depindă
de

modulele care implementează detalii.

Ultimul
principiu
din
listă
(în
engleză
The
Dependency
Inversion
Principle)
redă

faptul

rela
ț
iile
de
depe nden
ț
ă
de
la
nivel
înalt,
la
modulele
de
dependen
ț
e
de
nivel
inferior,

sunt
inversate,
ceea
ce
face
ca
modulatele
de
nivel
înalt

fie
independente
de
detaliile
de

implementare
a
modulelor
de
nivel
inferior.
Modulele
de
nivel
înalt
nu
trebuie

depindă
de

cele
de
nivel
scăzut,
amândouă
trebuind

depindă
de
abstractizare,
iar
abstractizarea
nu
ar

trebui să depindă de detalii. [10]

2.2 Aplica
ț
ia client

Aplica
ț
ia
client
(front-end-ul)
unui
site
web
(aplica
ț
ie
web
sau
mobile)
este
partea
pe

care
utilizatorul
o
vede
ș
i
cu
care
interac
ț
ionează
direct.
Acesta
gestionează
tot
ceea
ce

vizualizează
utilizatorii
prima
dată
în
browser
sau
aplica
ț
ie.
Provocarea
aferentă
dezvoltării

de
front-end
este

instrumentele
ș
i
tehnicile
folosite
pentru
a
crea
partea
pe
care
o
vede
ș
i
cu

care
interac
ț
ionează
utilizatorul
în
cadrul
unui
site,
se
modifică
constant,
iar
astfel

dezvoltatorul
trebuie

fie
responsabil
în
permanen
ț
ă
cu
privire
la
modul
în
care
se
dezvoltă

domeniul.

Obiectivul
de
a
proiecta
un
site
este
de
a
se
asigura
ca
atunci
când
utilizatorii
vor

deschide
site-ul,
ace
ș
tia
vor
vedea
doar
informa
ț
iile
necesare,
ce
se
doresc
afi
ș
ate,
într-un

format
care
este
u
ș
or
de
citit
ș
i
relevant.
Provocarea
cea
mare
în
acest
demers
vin
de
la

varietatea
de
dispozitive
cu
diferite
dimensiuni
ș
i
rezolu
ț
ii
ale
ecranului,
for
ț
ând
astfel

designerului

ia
în
considerare
aceste
aspecte
la
proiectarea
site-ului.
Este
nevoie
ca
ace
ș
tia


se
asigure

site-ul
lor
apare
corect
în
diferite
browsere
ș
i
sisteme
de
operare,
necesitând

astfel o planificare atentă de partea dezvoltatorului.

2.2.1 Framework-uri

Folosirea
unui
framework
(cadru)
pentru
a
construi
front-end-ul
are
multe
avantaje.

A
ș
a
numitele
„CSS
fram eworks”
sunt
pachete
care
con
ț
in
coduri
prescrie,
standardizate
în

fi
ș
iere
ș
i
foldere.
Acestea
ne
oferă
o
baza
de
la
care

încep em

construim,
permi
ț
ând

flexibilitatea
cu
designul
final.
De
obicei,
front-end
framework-urile
con
ț
in
următoarele

componente:

22


o re
ț
ea car e facilitează organizarea elementelor de design ale site-ului web


stiluri
de
fonturi
definite
ș
i
dimensiuni
care
variază
în
acord
cu
func
ț
ia
sa

(tipografie diferită pentru titluri versus paragrafe etc.)


componente
pre-construite
ale
site-ului,
cum
ar
fi
panouri
laterale,
butoanele
ș
i

barele de navigare

Câteva
dintre
avantajele
folosirii
framework-urilor
în
front-end
sunt,
în
loc
de
a
porni

codul de la zero sunt următoarele:


economisirea
de
timp

evident,
dacă
se
începe
scrierea
fiecărei
linii
de
cod
de

unul
singur,
va
dura
mult
mai
mult
pentru
a
lansa
site-ul.
Framework-urile
ne

ajută să începem cu elementele de bază


adăugarea
unor
componente
de
bază,
la
care
nu
am
avea
acces
altfel.
Este
în

avantajul
nostru

avem
op
ț
iunea
de
a
aborda
un
alt
buton
sau
două,
fără
a

mai necesita vreun efort în plus


cunoa
ș
terea
sigură
a
codului

într-adevăr
func
ț
ionează.
În
loc

petrecem

mult
timp
pentru
a
ne
asigura

propriul
cod
nu
func
ț
ionează
(sau
nu
este

compatibil
cu
60%
din
browserele
web),
vom
ș
ti

utilizăm
codul
func
ț
ional

presetat

Câteva
dintre
cele
mai
populare
framework-uri
folosite
de
developerii
de
front-end

sunt:
Angular,
React,
Vut
etc.
În
continuare
voi
prezenta
framework-ul
Angular,
deoarece
pe

acesta l-am ales eu să lucrez la aplica
ț
ia de licen
ț
ă.

2.2.2 Mediul de dezvoltare

Programul
folosit
pentru
dezvoltarea
aplica
ț
ii
client
este
Visual
Studio
Code.
Acesta

integrează
simplitatea
unui
editor
de
cod
sursă
cu
instrumente
puternice
de
dezvoltare,

precum
completarea
ș
i
depanarea
codului.
Acesta
este
disponibil
pentru
mai
multe
sisteme
de

operare: macOS, Linux
ș
i Windows.

2.2.3 Angular Framework

Angular
este
un
tip
de
aplica
ț
ie
open
source
bazată
pe
TypeScript,
condusă
de
echipa

Angular
la
Google
ș
i
de
o
comunitate
de
persoane
ș
i
corpora
ț
ii.
Acesta
este
o
rescriere

completă
de
la
aceea
ș
i
echipă
care
a
construit
AngularJS
[11].
Angular
încurajează

23

dezvoltatorii

construiască
aplica
ț
ii
care

poată
fi
utilizate
pe
web,
mobil
sau
chiar
ș
i
pe

desktop.

Acest
framework
ne
permite

scriem
cu
u
ș
urin
ț
ă
SPA
(Single
Page
Applications

o

aplica
ț
ie
web
interac
ț
ionează
cu
utilizatorul
prin
rescrierea
dinamică
a
paginii
curente).

Dispune
de
func
ț
ii
precum:
legarea
datelor,
detectarea
modificărilor,
formulare,
rutare
ș
i

navigare
ș
i o implementa re HTTP.

2.3.1.1 Structura Angular

În continuare voi prezenta câteva din principalele fi
ș
iere din Angular.

e2e-directory

Acest
director
este
folosit
doar
pentru
teste.
Este
utilizat
pentru
a
crea
ș
i
configura
o

testare
end-to-end
(e2e).
Pe
scurt,
prin
testarea
de
la
un
capăt
la
celălalt,
se
testează

interac
ț
iunea
dintre
păr
ț
i
separate
ale
aplica
ț
iei,
inclusiv
apelurile
către
bacl-end.
În
principiu,

aplica
ț
ia va fi testată a
ș
a cum o va folosi utilizatorul.

node_modules-directory

Atunci
când
managerul
de
pachete
instalează
toate
dependen
ț
ele
pe
ma
ș
ina
noastră,
le

procesează
pe
toate
la
fel
în
directorul
node_modules.
În
mod
normal,
dimensiunea
acestui

director ajunge pe la sute de magaocte
ț
i.

src-directory

Întregul cod sursă este localizat în acest director, în directorul sursă.

src/app-directory

În
interiorul
directorului
de
aplica
ț
ii,
se
plasează
toate
fi
ș
ierele
care
modifică
aspectul

sau
func
ț
ionalitatea

aplic a
ț
iei.
Acestea
includ
componentele,
modulele,
serviciile,
gardienii
ș
i

conductele (pipes).

Angular
a
generat
deja
o
componentă
numită
AppComponent
în
acest
scop.
Se

compune
din
trei
fi
ș
iere:

app.component.ts,
app.component.html
ș
i
app.component.css.
De

asemenea a creat un nou modul: AppModule (app.module.ts).

src/assets-directory

24

În
acest
director
se
pot
plasa
bunurile
necesare
pentru
aplica
ț
ie,
cum
ar
fi:
imagini,

iconi
ț
e, fonturi etc. Acest e fi
ș
iere se vor difuza împreună cu aplic a
ț
ia creată.

src/assets-directory

Aici se păstrează fi
ș
iere care definesc variabilele din aplica
ț
ie

src/index.html

Acesta
reprezintă
fi
ș
ierul
rădăcină
al
aplica
ț
iei,
deoarece
este
singurul
fi
ș
ier
html,

livrat
în
browser.
Con
ț
ine
toate
meta
informa
ț
iile
din
aplica
ț
ie.
De
asemenea
trebuie

con
ț
ină
eticheta
elementu lui
rădăcină
al
aplica
ț
iei
din
interiorul
corpului.
Valoarea
implicită

este:
<app-root></app-root>.

Pe
lângă
acest
aspect,
în
interiorul
fi
ș
ierului
se
poate
scrie
cod

html normal.

src/main.ts

Fi
ș
ierul
principal
.ts
este
punctul
de
intrare
al
aplica
ț
iei.
Tot
ceea
ce
se
află
în

interiorul
acestui
fi
ș
ier
este
apelul
de
func
ț
ii
pentru
a
bootstra
aplica
ț
ia
în
sine.
Aici
se
poate

specifica modul în care modulul angular ar trebui să fie boostrapat.

src/styles.css

Aceasta este foaia de stil globală. Stilurile definite aici sunt aplicate întregii aplica
ț
ii.

src/test.ts

Seamănă
cu
main.ts,
doar

este
pentru
testare.
Con
ț
ine
configura
ț
ia
suplimentară

necesară pentru unit teste.

scr/tsconfig.app.json

Acesta
este
un
fi
ș
ier
de
configurare
de
tip
script,
care
include
informa
ț
ii
despre
modul

în care TypeSript trebuie să fie compilat în JavaScript.

scr/tsconfig.spec.json

La
fel
ca

tsconfig.app.json

,
această
configura
ț
ie
se
aplică
numai
atunci
când
se

efectuează teste.

25

angular-cli.json

Acesta
este
fi
ș
ierul
de
configurare
principal
pentru
angular-cli.
În
interiorul
lui
se

poate
schimba
aproape
fiecare
comportament
implicit
al
CLI.
Acesta
este
util
dacă
se
dore
ș
te

altă
structură
de
directoare.
Apoi
îi
putem
spune
CLI-ului
unde
sunt
localizate
fi
ș
ierele

esen
ț
iale, cum ar fi

main. ts.

package.json

Fi
ș
ierul
stochează
toate
metadatele
despre
aplica
ț
ie.
Acesta
con
ț
ine
numele,
versiunea

ș
i
licen
ț
a
proiectului.
De
asemenea
con
ț
ine
informa
ț
ii
despre
toate
dependen
ț
ele
aplica
ț
iei,

ceea ce o face oarecum importantă.

tsconfig.json

Reprezintă
un
fi
ș
ier
de
configurare
typescript
(un
superset
de
JavaScript,
care
oferă
în

primul
rând
tipărire
op
ț
ională
statică,
clase
ș
i
interfe
ț
e),
care
include
informa
ț
ii
despre
modul

în care TypeScript trebuie să fie compilat în JavaScript.

2.3.1.2 Componentele Angular

Pentru
a
facilita
munca
depusă
în
construirea
aplica
ț
iei,
Angular
vine
cu
o
structură

pentru
aranjarea
codului
prin
adăugarea
de
blocuri
mici
care
odată
împreună
aranjate,
rezultă

p aplica
ț
ie frumoasă
ș
i func
ț
ională.

Componentele sunt compuse din trei fi
ș
iere: TypeScript, HTML
ș
i CSS.

26

Figura 8. Componentele Angular

Fi
ș
ierul TypeScript

Con
ț
ine
o
clasă ,
care
este
marcată
ca
o
componentă
de
către
decoratorul

@component.
Un
decorator
este
reprezentat
de
metadata
(date
despre
date)
despre
clasă.
Cu

decoratorul
@component,
această
clasă
ar
trebui
considerată
o
componentă.
Acest
fi
ș
ier
este

inima componentei, deoarece loca
ț
ia celorlalte două fi
ș
iere este descrisă aici.

Când
privim
fi
ș
ierele
angular,
identificarea
componentelor
este
foarte
simplă,

deoarece fiecare dezvoltator urmăre
ș
te conven
ț
ia de numire (naming convention).

Fi
ș
ierul HTML-Templa te

Al
doilea
fi
ș
ier
este
fi
ș
ierul
template
(
ș
ablon).
Tot
ceea
ce
are
de-a
face
cu
afi
ș
area
de

lucruri pe ecra, ar trebui sa fie scris în interiorul acestui template.

Fi
ș
ierul CSS

Ultimul
fi
ș
ier,
este
fi
ș
ierul
care
ț
ine
de
stil.
Acesta
con
ț
ine
stilurile
CSS.
Stilurile
unei

componente
sunt
definite
în
mod
implicit,
ceea
ce
înseamnă

dacă
avem
două
componente

care
au
ambele
clasa
css
„container”
(care
ar
trebui

arate
diferit)
nu
interferează
una
cu

cealaltă.
Ș
i de data aceast a, fi
ș
ierul urmează aceea
ș
i conven
ț
ie de nume.

Înainte
de
a
putea
cere
de
fapt
o
instan
ț
ă
a
unei
clase/
servicii
în
componen
ț
a
noastră,

trebuie

o
declarăm
undeva.
Aceasta
se
face
într-un
modul,
de
exemplu
în
modulul
de

aplica
ț
ii.

27

2.3.1.3 Injec
ț
ia de dependen
ț
ă în Angular

Injectarea
de
dependen
ț
ă
(sau
depedency
injection)
ne
permite

distribuim
cu

u
ș
urin
ț
ă
servicii
în
întreaga
aplica
ț
ie.
Astfel,
în
loc

adăugăm
o
instan
ț
ă
a
unei
clase
în

fiecare componentă, o cerem în constructorul componentelor noastre.

Framework-ul
Angular
va
avea
grijă
de
acesta
ș
i
va
furniza
instan
ț
a
solicitată
a
acelei

clase
la
timpul
de
execu
ț
ie.
Acest
aspect
ne
oferă
o
flexibilitate
mai
mare
ș
i
ne
permite

schimbăm rapid o dependen
ț
ă a tuturor componentelor.

2.3.1.4 Limbajele folosite în Angular

Principalele limbaje de cod folosite în Angular sunt: TypeScript, HTML
ș
i CSS.

TypeScript

TypeScript
este
un
superset,
o
extensie
de-a
limbajului
JavaScript.
TypeScript
este
un

limbaj
puternic
orientat
spre
obiect.
A
fost
proiectat
de
designerul
C#
(Anders
Hejilsberg).

Este atât un limbaj, cât
ș
i un set de instrumente [12].

JavaScript
este
una
dintre
tehnologiile
de
bază
ale
World
Wide
Web-ului.
Potrivit

unui
sondaj,
JavaScript
a
fost
limbajul
de
top
printre
dezvoltatorii
de
front-end
ș
i
nu
pare

să-
ș
i
piardă
popularitatea .
De
aceea,
astăzi
există
atât
de
multe
framework-uri
JavaScript.

Componentele
TypeScript
sunt:
limbajul

cuprinde
sintaxa,
cuvintele
cheie
ș
i
adnotările
de

tip
(type
annotations,
ajută
compilatorul
la
verificarea
tipurilor
ș
i
ajută
la
evitarea
erorilor

care se ocupă de tipurile de date)


compilatorul
TypeScript

converte
ș
te
instruc
ț
iunile
scrise
în
TypeScrip
la

echivalentul său JavaScript


serviciul
TypeScript
Language

expune
un
strat
suplimentar
în
jurul
miezului
de

compilare
de
bază,
care
sunt
aplica
ț
iile
asemănătoare
editorului.
Acest
serviciu

acceptă
setul
comun
al
unei
opera
ț
ii
tipice
de
editare,
cum
ar
fi
completarea

instruc
ț
iunilor, for matarea codului
ș
i a descrierii, colorare a etc.

28

Figura 9. Componentele TypeScript

HTML

(

Hyper Text Markup Language

)

Acesta reprezintă unul dintre cel mai utilizat limbaj pentru scrierea paginilor Web.


Hyper Text – se referă la modul în care paginile web (documentele HTML) sunt legate

între ele. A
ș
adar, link-ul ( legătura) disponibil pe o pagină web se nume
ș
te hyper text


Markup Language – după cum îi spune
ș
i numele, este un limbaj de marcare, ceea ce

înseamnă că folosirea codului HTML este pentru a „marca” un document text cu etichete care

îi spun unui browser web cum să-l structureze pentru a putea fi afi
ș
at Ini
ț
ial, codul HTML

[13]

La început, codul HTML a fost dezvoltat cu inten
ț
ia de a defini structura

documentelor precum titluri, paragrafe, liste
ș
i a
ș
a mai departe, pentru a favoriza schimbul de

informa
ț
ii
ș
tiin
ț
ifice între cercetători. Însă, acum acest limbaj este folosit pe scară largă chiar,

pentru a formata pagini web cu ajutorul tag-urilor diferite disponibile în limbajul HTML.

CSS

(Cascading Style Sheets)

CSS
este
un
limbaj
de
design
simplu,
destinat
simplificării
procesului
de
prezentare
a

paginilor
web.
Acesta
se
ocupă
de
aspectul
unei
pagini
web.
Prin
utilizarea
CSS,
se
poate

controla
culoarea
textului,
stilului
ș
i
a
fonturilor,
distan
ț
a
dintre
paragrafe,
modul
în
care
sunt

dimensionate
ș
i
dispuse
coloanele,
ce
imagini
de
fond
sau
culori
sunt
utilizate,
modelele
de

aspect,
varia
ț
iile
de
afi
ș
are
pentru
diferite
dispozitive
ș
i
dimensiunile
ecranului,
precum
ș
i
o

varietate
de
alte
efecte
[14].
CSS
este
unul
dintre
limbajele
care
se
înva
ț
ă
u
ș
or
ș
i
oferă
un

control bun asupra prezentării unui document HTML.

29

Câteva dintre avantajele CSS sunt:


salvează
timp

se
poate
scrie
CSS
o
dată,
iar
apoi
codul
poate
fi
reutilizat
în
mai
multe

pagini HTML


încărcarea
rapidă
a
paginilor

prin
utilizarea
CSS,
nu
este
necesară
scrierea
tag-urilor

HTML
de
fiecare
dată.
Se
poate
scrie
o
regulă
CSS
a
unei
etichete
ș
i
apoi
aplicată
la
toate

apari
ț
iile etichetei. Astfel , prin mai pu
ț
in cod scris reies perioade de descărcare mai rapide


între
ț
inere
u
ș
oară

pentru
a
face
o
schimbare
globală,
se
modifică
simplu
stilul
ș
i
toate

elementele paginii web vor fi actualizate automat


compatibilitatea
cu
mai
multe
dispozitive

prin
paginile
de
stil
se
permite
optimizarea

con
ț
inutului
pentru
mai
multe
tipuri
de
dispozitive.
Prin
utilizarea
aceluia
ș
i
document
HTML,

diferite versiuni ale unui site web pot fi prezentate pentru dispozitive portabile

2.3 Problema alocării de resurse

Alocarea
resurselor
este
o
problemă
frecventă
care
necesită
luarea
deciziilor.
Multe

tipuri
de
resurse
comune
(cum
ar
fi
timpul,
financiarul,
umanul,
calculatul,
materialele
etc.)

sunt
alocate
într-o
manieră
colaborativă
pentru
a
concilia
opinii
divergente
ș
i
pentru
a

satisface
criteriile
de
bunăstare
sau
corectitudine.
Această
problemă
apare
în
multe
situa
ț
ii
din

lumea
reală
atunci
când
un
grup
trebuie

împartă
profiturile
sau
activele
de
afaceri,

resursele naturale sau artificiale, foaia de lucru etc.[15]

Alocarea
resurselor
este
văzută
ca
o
problemă
colectivă
de
luare
a
deciziilor
de

agregare
a
preferin
ț
elor
individuale
pentru
o
alternativă
de
alocare
a
resurselor
între
membrii

unui
grup.
Resursele
pot
fi
o
singură
resursă
divizată
(omogenă
sau
eterogenă)
sau
multiple

resurse
indivizibile
(o
singură
unitate
sau
mai
multe
unită
ț
i,
care
pot
fi
sau
nu
pot
fi

distribuite). [15]

În
multe
probleme
de
optimizare
se
urmăre
ș
te
alocarea
unui
set
limitat
de
resurse
a

unui
grup
de
persoane
cu
cerin
ț
e.
Astfel
de
alocări
pot
fi,
în
mod
firesc,
văzute
ca
vectori,
cu

o singură coordonată reprezentând fiecare individ.

30

2.3.1
Comportamentul
strategic
atunci
când
alocăm
bunuri
indivizibile

secven
ț
ial

Există
multe
situa
ț
ii
în
care
trebuie

împăr
ț
im
elemente
între
agen
ț
i.
Am
putea
dori


împăr
ț
im
locurile
la
studen
ț
i
în
cadrul
cursurilor
sau
jucători
în
echipe.
Există
o
varietate

de
de
mecanisme
folosite
pentru
a
folosi
această
divizare
fără
„plă
ț
i
secundare”.
De
exemplu,

ș
coala
de
afaceri
Hardva rd
folose
ș
te
mecanismul
Draft
(proiectar e)
pentru
alocarea
cursurilor

pentru
studen
ț
i
(Budish
ș
i
Cantillon
2007).
Acest
mecanism
generează
ordinea
priorită
ț
ii

studen
ț
ilor
uniform,
la
întâmplare.
Cursurile
sunt
apoi
alocate
studen
ț
ilor
în
mai
multe
runde.

Fiecare
elev
este
alocat
cursului
preferat,
acesta
fiind
încă
disponibil
pentru
a-
ș
i
schimba

ordinea
priorită
ț
ii.
Din
păcate,
acest
mecanism
nu
este
dovadă
a
strategiei,
studen
ț
ii
trebuind

să-
ș
i aleagă în mod strate gic cursurile (Budish
ș
i Cantillon 2007).

Bourvet
ș
i
Lang
(2011)
iau
în
considerare
aspectele
computa
ț
ionale
ale
unei
proceduri

de
alocare
secven
ț
ială
(studiată
mai
devreme
de
Brams
ș
i
al
ț
ii)
care
generalizează
mai
multe

aspecte
ale
mecanismului
Draft.
Procedura
este
parametrizată
de
o
politică,
o
secven
ț
ă
în
care

agen
ț
ii
se
rotesc
pe
rând
pentru
a
alege
elemente.
De
exemplu,
la
fel
ca
ș
i
în
Draft,
cu
doi

agen
ț
i
ș
i
patru
obiecte,
politica
1221

prima
ș
i
ultima
alegere
primului
agent,
iar
celui
de-al

doilea agent îi repartizează al doilea
ș
i al treilea obiect.

O
perspectivă
bună
a
acestui
mecanism
este

preferin
ț
ele
agen
ț
ilor
nu
trebuie

fie

provocată.
Bouveret
ș
i
Lang
î
ș
i
asumă
faptul

agen
ț
ii
au
utilită
ț
i
adi
ț
ionale
date
de
o
func
ț
ie

comună
de
notare
(de
exemplu,
scoruri
Borda
sau
lexicografice).
Când
agen
ț
ii
au
aceea
ș
i

preferin
ț
ă
de
ordonare,
toate
politicile
dau
aceea
ș
i
sumă
a
utilită
ț
ilor,
iar
mecanismul
este

dovada
strategiei.
Atunci
când
agen
ț
ii
au
comenzi
de
preferin
ț
e
diferite,
comportamentul

strategic
poate
fi
profitabil.
Scopul
acestei
lucrări
este
de
a
studia
aspectele
computa
ț
ionale

ale unui astfel de comportament strategic.

Formal,
avem
un
set
G
de
m
elemente
pe
care
le
împăr
ț
im
între
n
agen
ț
i.
Agentul
i

reprezintă preferin
ț
ele ei prin ordinul liniar Pi peste G. O politică:

O = o1o2….. om


{1, . . . , n}

m

define
ș
te
un
mecanism
de
alocare
în
a
cărui
etapă,
un
agent
selectează
un
element.
Cu
doi

agen
ț
i
scriem
alocarea
(P1,
P2,
O),
construirea
fiind
cu
O,
având
în
vedere
ordinele
de

preferin
ț
ă
P1
ș
i
P2
ș
i
presupunând

agen
ț
ii
sunt
adevăra
ț
i.
Prin
aceasta,
în
fiecare
etapă
un

31

agent
î
ș
i
alege
cel
mai
preferat
element
încă
disponibil.
Noi
scriem
rev(P1)
pentru
a
inversa

(rev
de
la
reverse
=
a
inversa)
preferin
ț
ele
P1
ș
i
rev
(O)
pentru
inversarea
ordinului
de
alocare

în politica O.

[16]

Exemplu 1

Fie G = {1,……6}
ș
i O = 1 2121.

Preferin
ț
ele agentului P1 = 1 > 2 > 3 > 4 > 5 > 6

Preferin
ț
ele agentului P2 = 4 > 6 > 2 > 1 > 5 > 3

Obiectul alocat în fiecare rundă a alocării (P1, P2, O) este ilustrată în tabela următoare

O

1

2

1

2

2

1

obiect

1

4

2

6

5

3

2.3.1.1 Comportamentul strategic

Bouveret
ș
i
Lang
(2011)
iau
în
considerare
situa
ț
iile
în
care
agentul
încearcă

ob
ț
ină

o
alocare
mai
bună
prin
alegerea
strategică,
presupunând

to
ț
i
ceilal
ț
i
agen
ț
i
aleg
cu

sinceritate.
Cu
ajutorul
scorurilor
lexicografice,
ace
ș
tia
arată

strategia
optimă
pentru
un

agent
dat
cu
o
anumită
politică
poate
fi
calculată
în
timp
polinomial,
presupunând

al
ț
i

agen
ț
i
aleg
cu
sinceritate .
Ace
ș
tia
consideră

aflarea
strategiei
optime
este
NP-hard
pentru

scorurile
Borda
(o
familie
e
metode
electorate
cu
un
singur

ș
tigător,
în
care
alegătorii
au

op
ț
iuni
sau
candida
ț
i
în
ordinea
preferin
ț
elor).
Se
pune
problema
ca
un
agent
poate

aleagă

strategic
în
timp
ce
ceilal
ț
i
nu
o
fac.
Alocarea
secven
ț
ială
se
pretează
la
o
analiză
teoretică
a

jocului
unde
căutăm
un
echilibru
Nash
nu
î
ș
i
poate
îmbunătă
ț
ii
alocarea
prin
abaterea

unilaterală de la strategia de alegere.

Vedem
procedura
de
alocare
ca
un
joc
secven
ț
ial
repetat
în
care
to
ț
i
agen
ț
ii
au

informa
ț
ii
complete
despre
ordinarea
preferin
ț
elor
celorlal
ț
i
agen
ț
i.
Atunci
când
o
politică
are

un
agent
care
alege
la
rândul
său
mai
multe
elemente,
considerăm

acestea
reprezintă
o

singură
mi
ș
care
(deci
dacă
un
agent
alege
b,
apoi
îl
preferă
pe
a,
alegerea
nu
este
una

sănătoasă).
Putem
folosi
induc
ț
ia
backward
(inversă)
pentru
a
găsi
echilibrul
Nash
perfect
al

subjocului
(SPNE

subgame
perfect
Nash
equilibrium).
Când
agen
ț
ii
au
acea
ș
i
preferin
ț
ă
la

32

ordonare,
propozi
ț
ia
6
(Bouveret
ș
i
Lang)
demonstrează

aceasta
este
alegerea
sinceră.
Pe

de
altă
parte,
când
ordinele
de
preferin
ț
ă
sunt
diferite,
există
echilibrul
în
care

comportamentul nu este sincer.

Exemplu 2

Luam în considerare 4 elemente
ș
i politica alternativă.

Să presupunem că primul agent are ordinul de preferin
ț
ă: 1 > 2 > 3 > 4

în timp ce al doilea are ordinul de preferin
ț
ă: 4 > 2 > 3 > 1

Alegerea
sinceră
alocă
1
ș
i
2
primului
agent,
iar
4
ș
i
3
alocă
celui
de-al
doilea
agent.

Cu
toate
acestea
al
doilea
agent
nu
poate
exploata
sinceritatea
primului
ș
i
manipularea

mecanismului
de
a
ob
ț
ine
o
alocare
mai
bună.

presupunem

primul
agent
alege
sincer
1,

dar
cel
de-al
doilea
alege
2.
Acum,
primul
agent
nu
poate
face
altceva
decât

aleagă
3,

lăsând
agentului
doi

aleagă
4.
În
acest
fel,
al
doilea
agent
ob
ț
ine
o
alocare
mai
bună
(4
ș
i

2),
iar
primul
prime
ș
te
o
alocare
mai
slabă
(1
ș
i
3).
Pentru
a
preveni
acest
lucru,
primul
agent

poate

aleagă
în
mod
strategic
printr-o
alegere
nesigură
prima
dată
2.
Ce
mai
rea
alegere

pentru
al
doilea
agent
este

aleagă
1.
Indiferent
de
celălalt
element,
a
doilea
agent
alege
(3

sau
4),
iar
primul
agent
va
alege
elementul
lor
cel
mai
preferat,
1.
Prin
urmare,
primul
agent

se
termină
cu
1
ș
i
2,
care
a
fost
aceea
ș
i
alocare
finală
ca
ș
i
în
cazul
sincer.
Cu
toate
acestea,

prin
alegerea
nescrisă
în
acest
fel,
primul
agent
împiedică
al
doilea
agent

manipuleze

rezultatul
ș
i
agravarea
alocării
acestora.
Această
strategie
nesinceră
pentru
primul
agent

(alegerea
apoi
1)
ș
i
strategia
sinceră
pentru
al
doilea
agent
(alegerea
4
apoi
3)
este
SPNE

găsită în induc
ț
ia backwa rd.

Comportamentul pentru 2 agen
ț
i

Cu
doi
agen
ț
i,
utilită
ț
i
adi
ț
ionale
ș
i
politica
strict
alternativă,
Kohler
ș
i

Chandraesekaran
(1971)
demonstrează

SPNE
poate
fi
calculat
în
timp
liniar
prin
simpla

inversare
a
politicii
ș
i
preferin
ț
ei
de
ordonare.
Avem
următoa rea
extensie
surprinzătoare:

pentru
doi
agen
ț
i
ș
i
orice
politică
(nu
doar
o
alternare
strictă),
un
SPNE
poate
fi
calculată
în

timp
polinomial,
iar
acest
lucru
este
unic,
cu
condi
ț
ia
ca
niciun
agent

nu
aibă
aceea
ș
i

utilitate pentru orice pereche de elemente.

Teorema
1:
Cu
doi
agen
ț
i
ș
i
utilită
ț
i
adi
ț
ionale
pentru
orice
politică
O,
alocare
(rev(P2),

rev(P1),
rev(O))
este
un
SPNE.
Mai
mult
de
atât,
alocarea
este
ș
i
unică
dacă
ambii
agen
ț
i
au

preferin
ț
e stricte fa
ț
ă de obiecte.

33

Comportamentul pentru 3 agen
ț
i

Cu 3 agen
ț
i este p osibil să nu mai existe un SPNE.

Exemplu 3

Să presupunem că agentul 1
ș
i 3 au preferin
ț
ele: 1 > 2 > 3 > 4

iar agentul 2 are preferin
ț
ele: 3 > 4 > 1 > 2

Noi
luăm
în
considerare
politica
1231.
Există
două
SPNE.
În
primul,
agen
ț
ii
aleg
cu

sinceritate.
Agentul
1
prime
ș
te
elementele
1
ș
i
4,
agentul
2
prime
ș
te
elementul
3
ș
i
agentul
3

prime
ș
te
elementul
2.
În
celălalt
SPNE,
agentul
1
alege
mai
întâi
punctul
3
strategic.
Agentul

2
ș
i
3
(care
nu
au
niciun
stimulent,
ci

aleagă
sincer)

ob
ț
ină
elementele
4
ș
i
respectiv
1,

lăsând
elementul
2
pentru
agentul
1.
Cu
utilită
ț
ile
Borda,
agentul
1
are
aceea
ș
i
utilitate
în

ambele.

Acest
exemplu
poate
fi
adaptat
pentru
a
demonstra

SPNE
depinde
de
utilită
ț
ile

reale
ș
i nu doar de ordine a preferin
ț
elor. [16]

2.3.2 Algoritmi implementa
ț
i

În
cadrul
aplica
ț
iei
am
folosit
doi
algoritmi
pentru
repartizarea
modelelor
în
func
ț
ie
de

preferin
ț
ele
fiecărui
designer,
astfel
încât
acestea

fie
disponibile
pentru
o
singură

prezentare
pe
zi.
Algoritmii
folosi
ț
i
sunt:
Adjusted
Winner
(câ
ș
tigător
ajustat)
ș
i
Descending

Demand (cererea descendentă) care urmează să fie descri
ș
i în continuare.

2.3.2.1 Adjusted Winner


ș
tigătorul
ajust at
(Adjusted
Winner
cu
N
=
2)
este
descris
de
(Brams
ș
i
Taylor

1996)
ș
i
se
referă
la
două
persoane
sau
două
grupuri
cu
interese
diferite.
Func
ț
ia
de
evaluare

este
aditivă
ș
i
poate
necesita
una
dintre
resurse
ș
i
sfâr
ș
itul
protocolului
de
alocare.
Protocolul

este
echitabil,
fără
invidie,
eficient
Pareto

(reprezintă
o
stare
în
care
îmbunătă
ț
irea
unei

resurse
nu
este
posibilă
fără
deteriorarea
alteia)

.
Se
compune
din
următoarea
secven
ț
ă
de

pa
ș
i:

1.
Fiecare
persoană
distribuie
un
anumit
număr
de
puncte
(adică
100)
peste
resurse

pentru a reflecta evaluarea lui pentru fiecare element;

34

2.
Fiecare
resursă
este
dată
ini
ț
ial
individului
care
îi
atribuie
cel
mai
mare
număr
de

puncte.
Dacă
avem
egalitate
pentru
o
resursă,
acea
resursă
nu
va
fi
atribuită
niciuneia

dintre ele;

3.
Fiecare
persoană
însumează
numărul
de
puncte
totale
pe
care
le-a
primit
ș
i
cel
care
a

primit cel mai mic număr de puncte acum este dat elementului care a avut o egalitate;

4.
Dacă
numărul
de
puncte
totale
pe
care
fiecare
persoană
le-a
primit
este
egal,
stopăm.

În
caz
contrar,
resursele
sunt
transferate
de
la
cei
mai
boga
ț
i
la
cei
mai
săraci
până

când
transferul
de
resurse
este
transferat
de
la
cel
mai
bogat
la
cel
mai
sărac,
până

când
mutarea
unei
resurse
va
determina
cei
mai
boga
ț
i

aibă
mai
pu
ț
ine
puncte

totale
decât
cei
mai
săraci.
Această
ultimă
resursă
transferată
trebuie
împăr
ț
ită.

Resursele sunt transferate în ordinea ascendentă a scorului lor asociat;

5.
Scorul
se
calculează
prin
împăr
ț
irea
punctelor
date
de
cele
mai
bogate
către
o
resursă

ș
i a punctelor date de cele mai sărace la aceea
ș
i resursă; [15]

2.3.2.2 Descending Demand

Cererea
descendentă
(Descending
Demand
cu
N>
=
3)
a
fost
propusă
de
Herreiner
ș
i

Puppe
(2002).
Aceasta
presupune
o
ordonare
liniară
asupra
subseturilor
de
resurse.
Prin

urmare,
protocolul
nu
este
adecvat
pentru
un
număr
mare
de
resurse.
Protocolul
este
egalitar

ș
i Pareto eficient. Etapele protocolului sunt:

1.
Protocolul
începe
prin
stabilirea
ordinii
în
care
indivizii
î
ș
i
vor
exprima
pachetul
de

resurse preferat;

2.
În
această
ordine
predefinită,
indivizii
vor
primi
mai
întâi
subsetul
cel
mai
preferat
de

resurse.
Dacă
după
această
rundă
există
o
alocare
fesabilă
prin
combinarea
doar
a
subseturilor

de
resurse
men
ț
ionate
până
acum,
protocolul
se
opre
ș
te.
În
caz
contrar,
în
urma
aceleia
ș
i

ordini
predefinite,
fiecare
individ
va
da
al
doilea
subset
cel
mai
preferat
de
resurse
ș
i
va

încerca din nou să găsească o alocare fezabilă;

3.
Protocolul
continuă
în
acest
fel
până
când
se
găse
ș
te
o
alocare
fezabilă.
Atunci
când

există mai multe solu
ț
ii fezabile, se va alege eficien
ț
a Pareto [15];

2.3.2 Utilitatea algoritmului Adjusted Winner

35

Suntem
în
căutarea
unei
situa
ț
ii
în
care
două
persoane
se
află
în
conflict
total.

presupunem

Alice
si
Bob
divor
ț
ează,
iar
ace
ș
tia
sunt
nevoi
ț
i
să-
ș
i
împartă
bunurile.
O

modalitate este dată de procedura Adjusted Winner. Procedura este dată de următoarele:

1.
Fiecărui
individ
are
100
de
puncte
ș
i
are
sarcina
de
a
atribui
puncte
fiecărui
element

care
trebuie

fie
luat.
Mai
multe
puncte
înseamnă

individul
are
preferin
ț
e
mai

puternice
pentru
a
primi
respectivul
bun.
Din
nou,
presupunem

fiecare
individ
este

lacom. De asemenea, presupunem că ace
ș
ti concuren
ț
i nu cunosc punctele celuilalt;

2.
Persoana
care
a
atribuit
cele
mai
multe
puncte
pe
elemente
prime
ș
te
ini
ț
ial
elementul.

Se
adaugă
punctele
pentru
fiecare
persoană
pentru
cât
crede

a
atribuit.
Dacă
este

egalitate,
bunul
este
dat
persoanei
cu
cele
mai
pu
ț
ine
puncte.
Persoana
cu
cele
mai

multe puncte va fi ini
ț
ial declarată câ
ș
tigătoare, iar celălal t pierzător;

3.
Pentru
fiecare
obiect
dat

ș
tigătorului
ini
ț
ial,
se
va
calcu la
raportul
de
puncte.
Acesta

se va calcula prin împăr
ț
irea punctelor câ
ș
tigătorului la punctele pierzătorului;

4.
Se
începe
mutarea
obiectelor
de
la

ș
tigătorul
ini
ț
ial,
la
pierzătorul
ini
ț
ial
în
ordine

crescătoare
a
punctelor.
Se
opre
ș
te
când
se
ajunge
ca
un
element
a
cărui
mutare
va

determina

ș
tigătorul
ini
ț
ial

aibă
mai
pu
ț
ine
puncte
decât
cel
pierzător
ini
ț
ial.

Acest element va trebui reprezintă un element partajat;

5.
Fie
x
reprezentând
partea
frac
ț
ională
a
elementului
partajat
care
va
fi
mutat
de
la


ș
tigătorul
ini
ț
ial,
la
pierzătorul
ini
ț
ial.
Se
va
scrie
o
formulă
care
echivalează
totalul

punctelor fiecărei păr
ț
i după partajarea acestui element;

6.
Se
rezolvă
ecua
ț
ia
ș
i
se
analizează
diviziunea
finală.
Se
verifică
dacă
totalulurile
de

puncte sunt egale; [17]

36

Exemplu: Alice
ș
i Bob di vor
ț
ează

Luăm
în
calcul
faptul

Alice
ș
i
Bob
folosesc
procedura
Adjusted
Winner
ș
i
alocă

punctele astfel:

Obiect

Alice

Bob

Contul de retragere

50

40

Casă

20

35

Cabana de vară

15

14

Investi
ț
ii

10

6

Barcă

5

5

TOTAL

100

100

Pasul
1:

Ini
ț
ial,
Alice
prime
ș
te
contul
de
retragere,
cabana
de
vară
ș
i
investi
ț
iile.
Bob

prime
ș
te ini
ț
ial casa. Subtotalul curent este:

Alice = 50 + 15 + 10 = 75

Bob = 35

Deoarece
Bob
are
subtotal
inferior,
îi
dăm
obiectul
pentru
care
au
egalitate,
barca.
Astfel

subtotalul este dat de:

Alice = 75

Bob = 40

Alice este câ
ș
tigătorul ini
ț
ial
ș
i Bob este pierzătorul ini
ț
ial.

Pasul
2:

Apoi
caclulăm
raportul
de
punctaj
pentru
fiecare
element
pe
care
Alice
a
primit

ini
ț
ial:

Contul de retragere: =
3
5
5
0
,
3

1
4

Cabana de vară: =
1
4
1
5
,
7

1
0

Investi
ț
ii: =
1
4
1
5
,
7

1
0

Pasul
3:

Cel
mai
mic
punctaj
este
cel
cu
cabana
de
vară.
Se
începe
transferarea
lui
de
la
Alice

la Bob. Astfel rezultă un nou subtotal:

Alice = 75 – 15 = 60

Bob = 40 + 14 = 54

37

Următorul
obiect
este
contul
de
retragere.
Dacă
îl
transferăm
de
la
Alice
la
Bob,
noul
subtotal

va fi:

Alice = 60 – 50 = 10

Bob = 54 + 40 = 94

Deoarece
acest
lucru
va
determina
ca

aibă
mai
pu
ț
ine
puncte

ș
tigătorul
ini
ț
ial
(Alice),
iar

atunci elementul partajat este contul de retragere.

Pasul
4:

Doar
pentru
a
recapitula,
actualul
subtotal
este
Alice
=
60
ș
i
Bob
=
54.
Apoi

transferăm
frac
ț
ia
x
a
contului
de
retragere
de
la
Alice
la
Bob.
Bob

ș
tigă
o
parte
din
contul

de
pensionare,
astfel
încât
noul
său
total
va
fi
54
+
54x
(cei
40
provin
din
punctul
total
pe

care
Bob
l-a
alocat
pentru
contul
de
retragere).
Alice
pierde
o
parte
din
contul
de
retragere,

astfel încât noul său cont va fi 60 – 50x.

Pasul 5:

Am stabilit apoi aceste două ecua
ț
ii egale:

54 + 40x = 60 – 50x

90x = 6

x=
=
6
9
0
1
1
5
,
%

6
7

Aceasta însemnă că Bob va primi 6,7% din contul de retragere, iar Alice va păstra 93,3%.

Situa
ț
ia finală

:

Alice ob
ț
ine investi
ț
iile
ș
i 93,3 % din contul de retragere.

Punctul său total este: 10 + 50 (0.933)
56.7.

Bob prime
ș
te casa, caban a de vară, barca
ș
i 6,7% din contul de retragere.

Punctul său total este: 35 + 14 + 5 + 40 (0,067)
.
6
,

5
7

Câteva observa
ț
ii despr e procedura Adjusted Winner


se aplică doar pentru doi candida
ț
i;


vom ignora cazul unui zero pentru un obiect;


dacă
există
un
singur
element,
atunci
acest
element
este
împăr
ț
it
în
mod
egal
între
cele

două;


dacă
există
mai
mult
de
un
element,
fiecărei
persoane
li
se
garantează
cel
pu
ț
in
o
parte

dintr-un element;


în
timpul
alocării
ini
ț
iale
a
acestei
proceduri,
va
exista
întotdeauna
un

ș
tigător
ini
ț
ial

ș
i
un
pierzător
ini
ț
ial.
Dacă
există
o
egalitate
în
alocarea
totală
a
punctelor,
atunci
s-a

terminat procedura, rezultând că obiectele au fost alocate în mod egal;

38


ordinea
alocării
ini
ț
iale
nu
contează.
O
dat
ce
se
decide

ș
tigătorul
ini
ț
ial,
toate

articolele sunt luate în considerare în scopul împăr
ț
irii;


dacă
există
un
element
în
care
se
află
egalitate
la
punctele
de
alocare,
cel
mai
probabil

acesta va deveni element partajat;


ritmul
ini
ț
ial
este
garantat
tuturor
obiectelor
care
au
fost
alocate
ini
ț
ial.
Aceste

elemente nu vor fi împăr
ț
ite;


din
cauza
limitei
de
100
de
puncte,
este
posibil
ca
ini
ț
ial

ș
tigătorului

i
se
aloce

ini
ț
ial toate eleme ntele;


când
se
ajunge
la
pasul
4,
de
re
ț
inut

x
este
procentul
elementului
partajat,
care
este

transferat
către
pierzător
ini
ț
ial.
De
exemplu,
dacă
x
=
43
%,
atunci
cel
care
pierde

ini
ț
ial ob
ț
ine 43% din element, în timp ce câ
ș
tigătorul ini
ț
ial va păstra 57%;


Din
cauza
erorilor
de
rotunjire,
este
posibil
ca
totalul
punctului
final

nu
se

potrivească, dar ar trebui să fie relativ apropiat unul de altul; [17]

3. Descrierea formală a aplica
ț
iei

3.1 Arhitectura aplica
ț
iei

Prin
arhitectura
aplica
ț
iei
se
sugerează
o
reprezentare
a
modului
în
care
mai
multe

aplica
ț
ii
sunt
pregătite

colaboreze.
Aceasta
încearcă

ofere
o
încredere

suita
de

aplica
ț
ii care este scalabil ă, fiabilă, disponibilă
ș
i u
ș
or de gestionat.

Sistemul este compus din aplica
ț
ia web, apica
ț
ia server
ș
i baza de date.

Figura 10. Arhitectura sistemului

39

3.1.1 Arhitectura aplica
ț
iei server

Aplica
ț
ia server s tă la baza controlării întregului sistem. Conectată la o bază de date,

stochează detaliile clien
ț
ilor, modelelor
ș
i opera
ț
iunile efectuate.

Figura 11. Aplica
ț
ia server

40

Figura 12. Designe-ul aplica
ț
iei WebApi

Modelul
arhitectural
Model-View-Controller
(MVC)
separă
o
aplica
ț
ie
în
trei

componente
principale:
Model,
Vizualizare
ș
i
Controlor.
Acest
model
ajută
la
crearea

aplica
ț
iei
fiind
mai
u
ș
or
de
actualizat
decât
la
aplica
ț
iile
tradi
ț
ionale
molitice.
Fiindcă

aplica
ț
ia este bazată pe m odelul MVC, aceasta con
ț
ine:


Modele: clasele care reprezintă datele aplica
ț
iei;


Vizualizări: componentele care afi
ș
ează interfa
ț
a cu utilizatorul aplica
ț
iei;


Controlor: clase care gestionează cererile browserului;

Acest
model
ajuta
la
crearea
aplica
ț
iei
prin
separarea
diferitelor
aspecte
ale
aplica
ț
iei

(logica
de
intrare,
de
ie
ș
ire
si
de
UI).
Modelul
specifică
unde
trebuie
localizat
fiecare
tip
de

logică în aplica
ț
ie.

3.1.2 Func
ț
ionalitate

Atunci
când
va
începe
aplica
ț
ia,
metoda
Main,
din
clasa
Program
este
apelată.
Aceasta

creează
o
gazdă
web
implicită
utilizând
configurarea
de
pornire,
expunând
aplica
ț
ia
prin

HTTP printr-un port specific.

namespace

ResourceAllocation.Api

{

public


class


Program

{

public


static


void

Main(

string

[] args)

{

CreateWebHostBuilder(args).Build().Run();

}

public


static

IWebHostBuilder CreateWebHostBuilder(

string

[] args) =>

WebHost.CreateDefaultBuilder(args)

.UseStartup<Startup>();

}

}

Figura 13. Clasa Main

Crearea modulului Domeniu

Stratul
modul,
sau
Domain
Layer,
va
avea
clasele
noastre
care
vor
reprezenta

designerii
ș
i arti
ș
ti/modele.

În
directorul
ResourceAllocation.Api
am
creat
un
nou
dosar
numit
Domain
în
care

am adăugat clasele noastre.

41

namespace

ResourceAllocation.Domain

{

public


class


Designer

: BaseEntity

{

public


string

Name {

get

;

set

; }

public


string

Surname {

get

;

set

; }

public


string

Mail {

get

;

set

; }

public


int

nrOfArtistsNeeded {

get

;

set

; }

public

DateTime DateTimeShow {

get

;

set

; }

public

String LocationShow {

get

;

set

; }

public

List<DesignerArtists> FavoriteArtists {

get

;

set

; } =

new

List<DesignerArtists>();

[NotMapped]

public

List<DesignerArtists> AllocatedArtists {

get

;

set

; }

[NotMapped]

public


int

Score {

get

;

set

; }

}

}

Figura 14. Clasa Designer din stratul Domeniu

namespace

ResourceAllocation.Domain

{

public


class


Artist

: BaseEntity

{

public


string

Name {

get

;

set

; }

public


int

Height {

get

;

set

; }

public


int

Weight {

get

;

set

; }

public


int

BreastSize {

get

;

set

; }

public


int

WaistSize {

get

;

set

; }

public


int

HipsSize {

get

;

set

; }

public


string

EyesColor {

get

;

set

; }

public


string

HairColor {

get

;

set

; }

public


string

Facebook {

get

;

set

; }

public


string

Instagram {

get

;

set

; }

public


string

Description {

get

;

set

; }

public


string

Photo {

get

;

set

; }

public


string

Gender {

get

;

set

; }

public

IList<DesignerArtists> FavoriteForDesigners {

get

;

set

; }

}

}


Figura 15. Clasa Artist din stratul Domeniu

Clasele
mo
ș
tenesc
o
altă
clasă
numită
BaseEntity
în
care
se
găsesc
proprietă
ț
ile
pentru

id,
pentru
a
identifica
designerul
ș
i
respectiv
modelul,
ș
i
proprietatea
pentru
data
la
care
au

fost înregistrate acestea în baza de date.

namespace

ResourceAllocation.Domain

{

public


class


BaseEntity

42

{

public

Guid Id {

get

;

set

; }

public

DateTime DateCreated {

get

;

set

; }

}

}


Figura 16. Clasa BaseEntity din stratul Domeniu

Proprietă
ț
ile
pentr u
aceste
clase
reprezintă
detaliile
necesare
depre
fiecare
în
parte.
De

exemplu,
la
arti
ș
ti
avem
nevoie
de
culoarea
ochilor,
iar
la
designeri
avem
nevoie
de
loca
ț
ia
la

care
se
desfă
ș
oară
prezen tarea
de
modă.
Pe
lângă
aceste
proprietă
ț
i
specifice,
regăsim
liste
de

tipul
clasei
DesignerArtists.
Pentru
ari
ș
ti,
în
această
listă
este
folosită
pentru
memorarea

designerilor
pentru
care
au
fost
favori
ț
i.
în
cadrul
clasei
de
designeri,
listele
respective
sunt

folosite pentru re
ț
inerea a rti
ș
tilor favori
ț
i
ș
i pentru cei aloca
ț
i.

namespace

ResourceAllocation.Domain

{

public


class


DesignerArtists

{

public

Guid DesignerId {

get

;

set

; }

public

Guid ArtistId {

get

;

set

; }

public

Artist Artist {

get

;

set

; }

public

Designer Designer {

get

;

set

; }

public


int

Order {

get

;

set

; }

}

}


Figura 17. Clasa DesignerArtists din stratul Domeniu

Pe
lângă
aceste
clase
importante
din
cadrul
stratului
Domeniu,
am
mai
creat
alte
clase

AlgorithmResults
ș
i Com monArtistEntity.

namespace

ResourceAllocation.Domain

{

public


class


AlgorithmResult

{

public

List<Designer> Designers {

get

;

set

; }

public


int

Score {

get

;

set

; }

public


double

TimeExecuted {

get

;

set

; }

}

}


Figura 18. Clasa AlgorithmResult din stratul Domeniu

Această
clasă
con
ț
ine
proprietă
ț
i
pentru
stocarea
unor
rezultate,
precum
scorul
ș
i

timpul, executate în urma algoritmului executat, dar
ș
i o listă de designeri.

namespace

ResourceAllocation.Domain

{

public


class


CommonArtistEntity

{

public

Guid FirstDesigner {

get

;

set

; }

43

public

Guid SecondDesigner {

get

;

set

; }

public

Guid ArtistId {

get

;

set

; }

}

}

Figura 19. Clasa CommonArtistEntity din stratul Domeniu

Clasa
con
ț
ine
proprietă
ț
i
pentru
memorarea
detaliilor
artistului
comun
la
cei
doi

designeri:
id-urile
pentru
primul
ș
i
al
doilea
designer
ș
i
id-ul
artistului
comun
în
lista
de

preferate ale celor doi designeri.

Acum,
pentru

avem
clasele
de
bază,
suntem
gata

le
folosim.
Începem
prin
a
scrie

endpoint-urile (punctele finale) care vor gestiona toate modelele
ș
i designerii.

În
modulul
de
controller-e
vom
adăuga
trei
clase
noi
numite
ArtistsController,

DesignerController
ș
i
ResourceAllocationController.
Prin
conven
ț
ie,
toate
clasele
din
acest

modul
care
se
termină
cu
sufixul
„Controller”
vor
deveni
controllerii
aplica
ț
iei
noastre.

Aceasta
înseamnă

ei
vor
face
fa
ț
ă
cererilor
ș
i
răspunsurilor.
Această
clasă
este
nevoită

fie
mo
ș
tenită
în
spa
ț
iul
de
nume
(namespace)
Microsoft.AspN etCore.Mvc.
Un
spa
ț
iu
de

nume constă dintr-un grup de clase, interfe
ț
e, enumera
ț
ii
ș
i structuri asociate.

Noul
controller
ar
trebui

răspundă
prin
rutele:
api/artists,
api/designeri
ș
i

api/resourceallocation.
Aceasta
se
realizează
prin
adăugarea
atributului
Route
(rută
sau

traseu)
deasupra
numelui
clasei,
specificând
un
substituent
care
indică
faptul

traseul
ar

trebui să utilizeze denumirea clasei fără sufixul controller-ului, prin conven
ț
ie.

[Route(

"api/[controller]"

)]

[ApiController]

public


class


ArtistsController

: ControllerBase

{

}


Figura 20. Ruta controller-ului

În
continuare
voi
prezenta
cum
sunt
tratate
cererile
GET
(a
ob
ț
ine).
De
exemplu,

atunci
când
cineva
solicită
date
din
/api/designers
prin
verbul
GET,
API-ul
trebuie

returneze to
ț
i designerii. Î n acest scop, am creat un serviciu pentru designeri.

La
nivel
de
concept,
un
serviciu
este,
în
esen
ț
ă,
o
clasă
sau
o
interfa
ț
ă
care
define
ș
te

metode
pentru
a
face
fa
ț
ă
unei
anumite
logici
de
afaceri.
Este
o
practică
obi
ș
nuită
în
multe

limbaje
de
programare
diferite
de
a
crea
servicii
pentru
a
gestiona
logica
afacerii,
cum
ar
fi

autentificarea
ș
i
autoriza rea,
plă
ț
ile,
fluxurile
complexe
de
date,
cache-ul
ș
i
sarcinile
care

necesită
interac
ț
iune
între
alte
servicii
sau
modele.
Folosind
serviciile,
putem
izola
cererea
ș
i

tratarea răspunsului printr-o logică reală, necesară îndeplinirii sarcinilor.

44

Crearea modulului pentru servicii

(Services)

O
clasă
de
servicii
este
un
design
pattern
numit
Repository
Pattern
(modul
de

depozitare), care este utilizat pentru gestiunea datelor din baza de date.

Prin
utilizarea
Repository
Pattern-ului
definim
clasele
de
depozit,
care
încapsulează
în

esen
ț
ă
toată
logica
pentru
a
gestiona
accesul
la
date.
Aceste
depozite
expun
motode
pentru
a

lista,
crea,
modifica
sau
ș
terge
obiecte
dintr-un
anumit
model.
Pe
plan
intern,
aceste
metode

vorbesc
cu
baza
de
date
pentru
a
efectua
opera
ț
ii
CRUD,
izolând
accesul
bazei
de
date
de

restul aplica
ț
iei.

Serviciciile
noastre
trebuie

discute
cu
depozitele
de
designeri,
arti
ș
ti
si
algorimtii

de alocare, pentru a putea efectua opera
ț
iuni.

În
directorul
ResourceAllocation.Api
am
creat
un
nou
modul
numit
Services
în
care

am
adăugat
alte
3
sub
module,
pentru
arti
ș
ti,
designeri
ș
i
algoritmii
de
alocare.
În
acestea
am

adăugat
interfe
ț
ele
cores punzătoare.
Interfe
ț
ele
ne
permit

adăugăm
comportamentul
dorit

de la implementarea reală.

Folosind
un
mecanism
cunoscut
ca
injec
ț
ie
de
dependen
ț
ă,
putem
implementa
aceste

interfe
ț
e
ș
i
le
putem
izola
de
alte
componente.
Practic,
atunci
când
folosim
injec
ț
ia
de

dependen
ț
ă, definim anum ite comportamente folosind o interfa
ț
ă.

După
acest
pas,
am
creat
clasele
necesare
care
implementează
interfe
ț
ele
respective.

Astfel, obligăm referin
ț
ele din interfe
ț
e, la clasele pe care le-am c reat.

Datorită
implementării
serviciilor,
codul
din
interiorul
controller-elor
se
schimbă
ș
i

devine (de exemplu pentru designeri):

using

System;

using

Microsoft.AspNetCore.Mvc;

using

ResourceAllocation.Domain;

using

ResourceAllocation.Services.Artists;

namespace

ResourceAllocation.Api.Controllers

{

[Route(

"api/[controller]"

)]

[ApiController]

public


class


ArtistsController

: ControllerBase

{

private


readonly

IArtistsService _artistsService;

public

ArtistsController(IArtistsService artistsService)

{

_artistsService = artistsService;

}

45

[HttpGet]

public

IActionResult Get()

{

var

result = _artistsService.GetAll();

return

Ok(result);

}

[HttpGet]

[Route(

"{id:Guid}"

)]

public

IActionResult Get(Guid id)

{

var

result = _artistsService.GetById(id);

return

Ok(result);

}

[HttpPut]

public

IActionResult Put(Artist entity)

{

_artistsService.Add(entity);

return

Ok();

}

[HttpPatch]

public

IActionResult Patch(Artist entity)

{

_artistsService.Update(entity);

return

Ok();

}

[HttpDelete]

[Route(

"{id:Guid}"

)]

public

IActionResult Delete(Guid id)

{

_artistsService.Delete(id);

return

Ok();

}

}

}


Figura 21. Ruta controller-ului

Am
definit
o
func
ț
ie
de
constructor
pentru
controller-ul
nostru
(un
constructor
este

apelat
atunci
când
este
creată
o
nouă
instan
ț
ă
a
unei
clase)
ș
i
prime
ș
te
o
instan
ț
ă
a
serviciului

IDesignerService.
Aceasta
însemnă

instan
ț
a
poate
fi
orice
care
implementează
interfa
ț
a
din

serviciu.
Am
stocat
această
instan
ț
ă
intr-o
variabilă
_designersService
privat,
pentru
citire.

Vom
folosi
acest
câmp
pentru
a
accesa
metodele
implementării
serviciului
nostru
de

categorii.

46

Ca
ș
i
remarcă
la
prefixul
de
subliniere
din
cadrul
variabilei,
aceasta
reprezintă
o
altă

conven
ț
ie
comună
care
indică
o
variabilă
privată.
Această
conven
ț
ie
nu
este
recomandată
de

conven
ț
ia
de
denumire
a
.NET-ului,
dar
este
o
practică
foarte
frecventă,
o
modalitate
de
a

evita
utilizarea
cuvântului
„this”
(acesta)
pentru
a
distinge

variabile
locale
a
clasei​
.
Eu

 
 
 

personal cred prin folosirea acestei conven
ț
ii, codul este mult mai curat pentru a fi citit.

Sub
constructor,
am
definit
metodele
care
se
ocupă
de
cererile
pentru
/api/designer/,

respectiv
metodele
de:
aducere
a
tuturor
designerilor,
de
aducere
a
unui
singur
designer
în

func
ț
ie de id-ul acestuia, de adăugare, actualizare
ș
i
ș
tergere a unui designer.

Configurarea dependin
ț
ei

Clasa
Startup
din
modulul
rădăcină
al
aplica
ț
iei
este
responsabilă
pentru
configurarea

tuturor
tipurilor
de
configura
ț
ii
atunci
când
începe
aplica
ț
ia.
În
metodele
ConfigureServices
ș
i

Configure
se
configurează
modul
în
care
ar
trebui

func
ț
ioneze
aplica
ț
ia
ș
i
componentele
pe

care trebuie să le utilizeze.

În
metoda
ConfigureServices
avem
doar
o
singură
linie
care
configurează
aplica
ț
ia

pentru
utilizarea
conductei
MVC
(Model
View
Controller),
ceea
ce
înseamnă
în
principiu

aplica
ț
ia
va
gestiona
cererile
ș
i
răspunsurile
folosind
clase
de
controller.
Prin
această
metodă

accesăm parametrul services, pentru a configura legăturile de dependen
ț
ă.

using

Microsoft.AspNetCore.Builder;

using

Microsoft.AspNetCore.Hosting;

using

Microsoft.AspNetCore.Mvc;

using

Microsoft.EntityFrameworkCore;

using

Microsoft.Extensions.Configuration;

using

Microsoft.Extensions.DependencyInjection;

using

Newtonsoft.Json;

using

ResourceAllocation.DataLayer;

using

ResourceAllocation.DataLayer.Designers;

using

ResourceAllocation.DataLayer.Artists;

using

ResourceAllocation.Services.Designers;

using

ResourceAllocation.Services.Artists;

using

ResourceAllocation.Services.ResourceAllocation;

using

ResourceAllocation.Api.Models;

using

Swashbuckle.AspNetCore.Swagger;

namespace

ResourceAllocation.Api

{

public


class


Startup

{

public

Startup(IConfiguration configuration, IHostingEnvironment env)

{

var

builder =

new

ConfigurationBuilder()

.SetBasePath(env.ContentRootPath)

47

.AddJsonFile(

"appsettings.json"

, optional:

false

, reloadOnChange:

true

)

.AddJsonFile(

$"appsettings.

{env.EnvironmentName}

.json"

, optional:

false

, reloadOnChange:

true

)

.AddEnvironmentVariables();

configuration = builder.Build();

Configuration = configuration;

}

public

IConfiguration Configuration {

get

; }

public


void

ConfigureServices(IServiceCollection services)

{

services.AddCors(options =>

{

options.AddPolicy(

"LocalCorsConfig"

, policy => policy.WithOrigins(

"http://localhost:4200"

));

});

services.AddMvc()

.AddJsonOptions(options => options.SerializerSettings.ReferenceLoopHandling =

ReferenceLoopHandling.Ignore)

.SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

services.AddTransient<IArtistsService, ArtistsService>();

services.AddTransient<IArtistsRepository, ArtistsRepository>();

services.AddTransient<IDesignersService, DesignersService>();

services.AddTransient<IDesignersRepository, DesignersRepository>();

services.AddTransient<IAdjustedWinnerAllocationService, AdjustedWinnerAllocationService>();

services.AddTransient<IDescendingDemandAllocationService, DescendingDemandAllocationService>();

var

connectionStrings =

new

ConnectionStrings();

Configuration.GetSection(

"ConnectionStrings"

).Bind(connectionStrings);

services.AddDbContext<ResourceAllocationDbContext>

(options => options.UseSqlServer(connectionStrings.ResourceAllocationApiContext));

services.AddSwaggerGen(c =>

{

c.SwaggerDoc(

"v1"

,

new

Info { Title =

"My API"

, Version =

"v1"

});

});

}

public


void

Configure(IApplicationBuilder app, IHostingEnvironment env)

{

app.UseDeveloperExceptionPage();

using

(

var

serviceScope = app.ApplicationServices.GetService<IServiceScopeFactory>().CreateScope())

{

var

context = serviceScope.ServiceProvider.GetRequiredService<ResourceAllocationDbContext>();

context.Database.EnsureCreated();

}

app.UseHttpsRedirection();

48

app.UseMvc();

app.UseCors(

"LocalCorsConfig"

);

app.UseSwagger();

app.UseSwaggerUI(c =>

{

c.SwaggerEndpoint(

"/swagger/v1/swagger.json"

,

"My API V1"

);

});

}

}

}

Figura 22. Clasa Startup

În linia de cod următoare, din clasa de mai sus, configurăm contextul bazei de date.

services.AddDbContext<ResourceAllocationDbContext>

(options => options.UseSqlServer(connectionStrings.ResourceAllocationApiContext));

Figura x. Configurarea contextului bazei de date

După
configurarea
contextului
bazei
de
date,
legăm
de
asemenea
serviciul
ș
i
depozitul

nostru la clasele respective.

services.AddTransient<IArtistsService, ArtistsService>();

services.AddTransient<IArtistsRepository, ArtistsRepository>();

services.AddTransient<IDesignersService, DesignersService>();

services.AddTransient<IDesignersRepository, DesignersRepository>();

services.AddTransient<IAdjustedWinnerAllocationService, AdjustedWinnerAllocationService>();

services.AddTransient<IDescendingDemandAllocationService,

DescendingDemandAllocationService>();


Figura 23. Legarea serviciului nostru de clase necesare

Cererile HTTP

Un exemplu de endpoint din cadrul aplica
ț
iei este următorul:

[HttpPost]

[Route(

"{id:Guid}/set-favourite-models"

)]

public

IActionResult SetFavouritesArtists(Guid id, [FromBody]List<Guid> ArtistIds)

{

_designersService.SetFavouriteArtists(id, ArtistIds);

return

Ok();

}

Figura x. Endpoint pentru setarea liste de modele favorite

49

Metodele
prezente
în
clasele
de
controller
sunt
numite
ac
ț
iuni
ș
i
au
această
semnătură

deoarece putem returna mai mult decât un posibil rezultat după ce se execută aplica
ț
ia.

În
acest
caz,
dacă
este
invalid
id-ul
designerului
sau
se
întâmplă
ceva
în
neregulă,
va

trebui

returnăm
un
răspuns
de
cod
400
(solicitare
gre
ș
ită),
care
con
ț
ine,
în
general,
un

mesaj
de
eroare
pe
care
aplica
ț
iile
client
le
pot
utiliza
pentru
a
trata
problema
sau
putem
avea

un răspuns 200 (succes) cu date dacă totul merge bine.

Exsită
mai
multe
tipuri
de
ac
ț
iuni
pe
care
le
putem
utiliza
ca
răspuns,
dar,
în
general,

putem folosi această interfa
ț
ă, iar ASP.NET Core va folosi o clasă implicită pentru aceasta.

Atributul
FromBody
îi
spune
lui
ASP.NET
Core

analizeze
datele
corpului
cererii
în

noua clasă de resurse.

Acum,
putem
pune
în
aplicare
noua
logică
de
rută.
Pa
ș
ii
care
trebuie
urma
ț
i
pentru
a

crea cu succes un nou designer sunt:


În
primul
rând,
trebuie

validăm
solicitarea
de
intrare.
Dacă
cerea
este
nevalidată,

trebuie să returnăm un răspuns de solicitare care con
ț
ine mesajele de eroare;


Dacă
cererea
este
validă,
apelăm
serviciul
nostru,
spunându-i

salveze
noul
nostru

designer.
Dacă
logica
de
salvare
este
executată
fără
probleme,
ar
trebui
returnat
un

răspuns
care
con
ț
ine
datele
noului
designer.
Dacă
nu,
ar
trebui

ne
dea
o
indica
ț
ie

procesul nu a reu
ș
it
ș
i un poten
ț
ial mesaj de eroare;

Aplicarea modelului de solicitare-răspuns

În
cele
ce
urmează
voi
prezenta
una
dintre
cele
trei
clase
(Designer,
Artists
ș
i

ResourceAllocation) în care am folosit modelul de solicitare-răspuns.

namespace

ResourceAllocation.Api.Controllers

{

[Route(

"api/[controller]"

)]

[ApiController]

public


class


DesignersController

: ControllerBase

{

private


readonly

IDesignersService _designersService;

public

DesignersController(IDesignersService designersService)

{

_designersService = designersService;

}

[HttpGet]

public

IActionResult Get()

{

50

var

result = _designersService.GetAll();

return

Ok(result);

}

[HttpGet]

[Route(

"{id:Guid}"

)]

public

IActionResult Get(Guid id)

{

var

result = _designersService.GetById(id);

return

Ok(result);

}

[HttpPost]

[Route(

"{id:Guid}/set-favourite-models"

)]

public

IActionResult SetFavouritesArtists(Guid id, [FromBody]List<Guid> ArtistIds)

{

_designersService.SetFavouriteArtists(id, ArtistIds);

return

Ok();

}

[HttpPut]

public

IActionResult Put(Designer entity)

{

_designersService.Add(entity);

return

Ok();

}

[HttpPatch]

public

IActionResult Patch(Designer entity)

{

_designersService.Update(entity);

return

Ok();

}

[HttpDelete]

[Route(

"{id:Guid}"

)]

public

IActionResult Delete(Guid id)

{

_designersService.Delete(id);

return

Ok();

}

}

}

Figura 24. Clasa Designer

După
validarea
datelor
de
solicitare
a
resurselor
către
modelul
nostru,
îi
transmitem

serviciului nostru să men
ț
ină datele.

Dacă
ceva
nu
reu
ș
e
ș
te,
API-ul
returnează
un
cod
de
eroare .
Dacă
nu,
API-ul
redă
noua

informa
ț
ia dorită (incluzâ nd datele)
ș
i o trimite clientului.

51

Testarea endpoit-urilor folosind Postman

Un
endpoint
HTTP
este
o
adresă
URL
vizată
în
aplica
ț
ia
web,
cum
ar
fi
în
cazul

nostru:

https://localhost:44304/api/

artists
care
combină
protocolul
utilizat
HTTPS
cu
loca
ț
ia

de
re
ț
ea
a
serverului
web
(inclusiv
portul
TCP):
localhost:44304
ș
i
ț
inta
URI

ResourceAllocation API.

MVC
invocă
clasele
controllerului
(
ș
i
metodele
de
ac
ț
iune
din
cadrul
acestora)
în

func
ț
ie
de
adresa
URL
primită.
Logica
implicită
de
rutare
a
adreselor
URL
folosită
de
MVC

utilizează un format ca acesta pentru a determina ce cod dorim să invocăm:

/[Controlor]/[NumeAc
ț
iune]/[Parametrii]

Formatul rutării se află în metoda Configure din fi
ș
ierul Startup.cs descrisă mai sus.

Răsfoind
la
adresa
https
de
mai
sus,
care
reprezintă
ș
i
metoda
de
întâmpinare,
aceasta

rulează
ș
i
returnează
lista
de
arti
ș
ti.
Aspectul
paginii
de
la
această
rută
în
urma
rulării

API-ului este reprezentată în imaginea de mai jos.

Figura 25. Endpoint pentru afi
ș
area arti
ș
tilor

Pentru
a
testa
endpoint-urile
în
aplica
ț
ia
Postman,
vom
porni
rularea
aplica
ț
iei
noastre

server.
Vom
introduce
adresa
API
în
câmpul
pentru
introducerea
adresei
URL
a
solicitării
ș
i

vom selecta castele de GET/ POST/ PUT/ PATCH/ DELETE în func
ț
ie de cererile dorite.

52

Figura 26. Afi
ș
area arti
ș
tilor cu PostMan

În
figura
de
mai
sus
este
reprezentată
afi
ș
area
tuturor
arti
ș
tilor
din
baza
de
date
prin

aplica
ț
ia
Postman.
In
partea
de
sus
a
figurii
se
observă
ruta
pe
care
i-am
dat-o,
iar
în
stânga

acesteia
este
selectat
modul
de
solicitare
(GET).
De
asemea,
în
această
fereastră
mai
este

afi
ș
at si codul „200 OK” ceea ce sugerează că a func
ț
ionat corespunzător.

53

3.2 Scenarii de utilizare

Figura 27. Scenarii de utilizare


Pornirea
server-ului:
în
momentul
în
care
este
pornit
serverul
de
date,
se
poate
ini
ț
ia

adăugarea
de
modele
sau
designeri.
Pentru
a
lucra
cu
baza
de
date,
server-ul
va
sta
tot

timpul pornit;


Adăugarea
de
modele
ș
i
designeri:
administratorul
are
pe
interfa
ț
a
aplica
ț
iei
câte
un

buton
pentru
adăugarea
de
modele
ș
i
de
designeri
ș
i
o
listă
cu
numărul
total
de
modele

ș
i
designeri
care
se
află
deja
înregistrat
în
baza
de
date.
După
apăsarea
butonului
de

adăugare,
va
apărea
pe
interfa
ț
ă
ecranul
de
adăugare
modele
ș
i
designeri,
detalii

despre
ace
ș
tia,
precum:
nume,
prenume,
dimensiuni
statură
fizică
(pentru
modele),

loca
ț
ia, data
ș
i ora desfă
ș
urării prezentării de modă (pentru designeri) etc.;


Modificarea
sau
ș
tergerea
unui
model
sau
a
unui
designer
deja
existent:

administratorul poate actualiza detaliile acestora;

54


Vizualizarea
listei
de
modele
precum
ș
i
cea
de
designeri.
Pe
lângă
această
posibilitate,

administratorul
poate
vedea
ș
i
detaliile
despre
fiecare
înregistrare
în
parte,
accesând

un buton care duce la respectivul model/ designer;

55

4. Descrierea aplica
ț
iei

4.1 Structura aplica
ț
iei server

În
următorul
capitol
vor
fi
prezentate
func
ț
ionalită
ț
ile
aplica
ț
iei
sub
forma
schemelor

logice
ș
i legătura între fer estrele din cadrul programului.

4.1.1 Metoda de alocare a modelelor

Fiecare
designer
î
ș
i
selectează
un
număr
cât
mai
mare
de
modele
(mai
mare
decât

numărul
necesar
de
modele)
pe
care
ș
i
le
dore
ș
te
în
cadrul
prezentării
de
modă,
în
ordinea

preferin
ț
elor.
În
acela
ș
i
timp,
designerul
trebuie
sa-
ș
i
selecteze
ș
i
data
împreună
cu
ora
la
care

se petrece evenimentul. Astfel, în func
ț
ie de aceste date îi se vor aloca modelele potrivite.

56

Figura 28. Schemă logică – metoda de alocare

Conform
figurii
anterioare,
este
prezentată
schema
logică
a
metodei
de
alocare
a
modelelor.

Aceasta se execută astfel:


Aceasta
începe
prin
adăugarea
de
modele
ș
i
designeri
în
baza
de
date,
împreună
cu

detaliile acestora;

57


Urmează
ca
fiecare
designer

î
ș
i
aleagă
câte
un
set
de
modele
preferate
(mai
multe

decât
are
nevoie)
ordonate
în
func
ț
ie
de
favorite,
pentru
a
fi
siguri

vor
avea
parte
de

cele mai dorite de ei, în urma alocării;


Se
verifică
dacă
în
cadrul
listei
de
designeri
există
cel
pu
ț
ini
doi
care

aibe

prezentarea în aceea
ș
i zi;


Dacă
ace
ș
tia
au
prezentarea
în
aceea
ș
i
zi,
atunci
se
trece
prin
algoritmii
de
alocare,
iar

în
cazul
în
care
modelele
preferate
se
suprapun,
acestea
vor
fi
alocate
corespunzător

pe baza algoritmilor;


Dacă
nu
sunt
designeri
care
prezintă
în
aceea
ș
i
zi
sau
chiar
dacă
există
dar
s-a
trecut

deja
prin
algoritmi,
urmează
pasul
în
care
designerilor
le
sunt
aloca
ț
i
atâtea
modele

cât au nevoie de fapt în cadrul prezentării proprii;

4.1.2 Algoritmii implementa
ț
i

Cum
am
descris
ș
i
în
capitolul
anterior,
algoritmii
folosi
ț
i
„Adjted
Winner”
ș
i

„Descending Demand” urmează sa fie expu
ș
i în următoarele rânduri sub formă de scheme.

58

4.1.2.1 Adjusted Winner

Figura 29. Schemă logică – algoritmul „Adjusted Winner”

59

Acest
algoritm
începe
după
ce
s-au
introdus
modelele
ș
i
după
ce
designerii
ș
i-au

selectat
acela
ș
i
număr
de
arti
ș
ti
pe
care
îl
preferă
în
prezentările
lor.
Se
parcurg
pe
rând
toate

modelele.
Dacă
se
întâlne
ș
te
un
model
care
este
preferat
de
cel
pu
ț
in
doi
designeri
care
doresc


prezinte
în
aceea
ș
i
zi,
atunci
alocarea
acestuia
se
face
conform
algoritmului.
Pa
ș
ii
sunt

următorii:


Modelul este alocat designerului care îl preferă mai mult.


De
exemplu,
dacă
modelul
este
cu
o
pozi
ț
ie
mai
sus
în
lista
de
preferate
al

primului
designer
decât
la
cel
de-al
doilea,
atunci
artista
va
fi
alocată
primului

designer.
Lista
celui
de-al
doilea
designer
urmează

fie
modificată
prin

ș
tergerea m odelul respectiv pentru care a pierdut lupta;


Dacă
modelul
se
află
pe
aceea
ș
i
pozi
ț
ie
la
to
ț
i
designerii,
modelul
va
fi
alocat

designerului care are scorul cel mai mare.


Scorul
reprezintă
suma
tuturor
pozi
ț
iilor
modelelor
alocate
până
în
acel

moment pentru fiecare designer în parte;


În
cazul
în
care
se
constată
ca
este
egal
scortul,
atunci
modelul
nu
va
fi
alocat

niciunuia dintre designerii respectivi;

Implementare software

În
fereastra
următoare
este
prezetată
implementarea
algoritmului
„Adjusted
Winner”

în limbajul de programare C#.

private

List<Designer> AdjustedWinner (List<Designer> designers,

List<CommonArtistEntity> commonArtists)

{

foreach

(var commonArtist

in

commonArtists)

{

var

firstDesigner = designers.First(x => x.Id == commonArtist.FirstDesigner);

var

firstDesignerArtistPosition = GetModelPosition(firstDesigner, commonArtist);

var

secondDesigner = designers.First(x => x.Id == commonArtist.SecondDesigner);

var

secondDesignerArtistPosition = GetModelPosition(secondDesigner, commonArtist);

if

(firstDesigner.DateTimeShow.Date.Equals(secondDesigner.DateTimeShow.Date))

{

if

(firstDesignerArtistPosition < secondDesignerArtistPosition)

60

{

RemoveCommonArtistFromDesigner(secondDesigner, commonArtist);

}

else


if

(firstDesignerArtistPosition > secondDesignerArtistPosition)

{

RemoveCommonArtistFromDesigner(firstDesigner, commonArtist);

}

else


if

(firstDesignerArtistPosition == secondDesignerArtistPosition)

{

if

(GetDesignerScore(firstDesigner) < GetDesignerScore(firstDesigner))

{

RemoveCommonArtistFromDesigner(firstDesigner, commonArtist);

}

else


if

(GetDesignerScore(firstDesigner) >

GetDesignerScore(secondDesigner))

{

RemoveCommonArtistFromDesigner(secondDesigner, commonArtist);

}

else

{

RemoveCommonArtistFromDesigner(firstDesigner, commonArtist);

RemoveCommonArtistFromDesigner(secondDesigner, commonArtist);

}

}

}

}

foreach

(var designer

in

designers)

{

alllocateNoOfNeededArtists(designer);

}

return

designers;

}

Figura 30. Implementare – Adjusted Winner

Explica
ț
ia codului pentru metoda de implementare este următoarea:

61


Se
crează
o
metodă
numită
„AdjustedWinner”
de
tipul
listei
„Designer”
cu
parametrii

de intrare: o listă de designeri
ș
i o listă de arti
ș
ti (modele) comune;


Se
parcurge
lista
de
modele
comune,
care
con
ț
ine
to
ț
i
arti
ș
tii
care
se
regăsesc
în
lista

de preferate a designerilor;


Se
ini
ț
ializează
două
variabile
în
care
se
re
ț
in
doi
designeri
care
sunt
la
rând
din

cadrul
listei
de
modele
comune:
„firstDesigner”
ș
i
„secondDesigner”.
De
asemenea,

se
mai
crează
două
variabile,
tot
pentru
ace
ș
ti
designeri,
în
care
se
memorează
pozi
ț
ia

artistului
comun
din
cadrul
fiecărei
liste
de
favorite:
„firstDesignerArtistPosition
”,

„secondDesignerArtistPosition ”;


Se
verifică
dacă
ace
ș
ti
designeri
au
data
de
prezentare
a
evenimentului
în
aceea
ș
i
zi,

iar
dacă
nu
au,
atunci
se
sare
direct
către
finalul
metodei
în
care
se
alocă
fiecărui

designer atâtea modele cât are nevoie pentru prezentare;


Dacă
ace
ș
tia
au
prezentarea
în
aceea
ș
i
zi,
atunci
se
începe
alocarea
modelelor

comune:


Se
compară
pozi
ț
iile
modelului
comun
din
cadrul
listelor
de
favorite
ale
celor

doi
designeri
verifică
dacă
pozi
ț
ia
modelului
de
la
primul
designer
este
mai

mică
(cu
cât
pozi
ț
ia
modelului
este
mai
mică,
cu
atât
modelul
este
mai

favorizat) decât pozi
ț
ia modelului celui de-al doilea designer;

ș
Se
verifică
dacă
pozi
ț
ia
modelului
de
la
primul
designer
este
mai
mică

(cu
cât
pozi
ț
ia
modelului
este
mai
mică,
cu
atât
modelul
este
mai

favorizat)
decât
pozi
ț
ia
modelului
celui
de-al
doilea
designer.
Dacă

este,
atunci
se
va
apela
metoda
„RemoveCommonArtistFromDesigner”

cu
parametrii
de
intrare:
„secondDesigner”
ș
i
„commonArtist”,
care

duce la
ș
tergerea modelului din lista celui de-al doilea designer;

ș
Altfel,
dacă
pozi
ț
ia
modelului
de
la
primul
designer
este
mai
mare

decât
pozi
ț
ia
modelului
designerului
următor,
se
va
apela
aceea
ș
i

metodă,
la
fel
ca
mai
sus,
doar

primul
parametru
va
fi
schimbat
în

„firstDesigner”


În
cazul
în
care
rezultă
egalitate,
se
va
apela
metoda
„GetDesignerScore”
prin

care
se
returnează
un
număr
care
reprezintă
scorul.
Acesta
sugerează
suma

tuturor
pozi
ț
iilor
ini
ț
iale
ale
modelelor
rămase
în
urma
ș
tergerilor
din
cadrul

fiecărei liste;

62

ș
În
cazul
în
care
scorul
primului
designer
este
mai
mic
decât
scorul

celui
de-al
doilea
designer
se
va
apela
aceea
ș
i
metodă
pentru
ș
tergerea

modelului
„RemoveCommonArtistFromDesigner”.
De
data
aceasta
se

va
efectua
ș
tergerea
modelului
de
la
primul
designer,
pentru

cu
cât

avem
un
scor
mai
mic
cu
atât
înseamnă

au
fost
selectate
cele
mai

favorite modele;

ș
În
cazul
în
care
scorul
primului
designer
este
mai
mare
decât
scorul

celui
de-al
doilea
designer,
se
va
apela
din
nou
aceea
ș
i
metodă
ca
mai

sus,
doar

se
vor
folosi
parametrii
necesari
pentru
ș
tergerea

modelului celui de-al doilea designer;

ș
Dacă
se
va
considera
egalitate,
atunci
modelul
va
fi
ș
ters
din
listele

ambilor designeri;


Urmează
alocarea
numărului
necesar
de
modele.
Se
parcurg
to
ț
i
designerii
pe
rând
ș
i

se
apelează
metoda
„allocateNoOfNeededArtists”
cu
parametrul
„designer”-ului
care

urmează,
deoarece
schimbările
care
au
fost
necesare
s-au
făcut
deja,
iar
acum

designerii
au
lista
cu
modele
alocate
corect.
Numărul
necesar
de
modele
pentru

fiecare designer este salvat în entitatea acestora;


Metoda se încheie prin returnarea listei de designeri, care con
ț
ine noile modificări.

63

4.1.2.2 Descending Demand

Figura 31. Schemă logică – algoritmul „Descending Demand”

64

Algoritmul
Descending
Demand
începe
la
fel
ca
algoritmul
anterior,
după
ce
s-au

introdus
modelele
ș
i
după
ce
designerii
ș
i-au
selectat
acela
ș
i
număr
de
arti
ș
ti
pe
care
îl

preferă
în
prezentările
lor.
În
cazul
în
care
doi
sau
mai
mul
ț
i
designeri
doresc

prezinte
în

aceea
ș
i zi, se efectuează u rmătorii pa
ș
i:


Se
ia
primul
set
de
modele
care
constă
în
numărul
necesar
de
modele
pentru

prezentare;


Se verifică dacă există cel pu
ț
in un model comun în aceste seturi


Dacă
există,
atunci
se
trece
la
următorul
set
ș
i
se
reia
pasul
anterior,
până
când

se
găse
ș
te
un
set
potrivit
de
modele,
până
când
nu
mai
există
modele
comune

în seturile la care s-a ajuns


Dacă nu există, modelele sunt alocate direct designerilor;

Implementare software

În
fereastra
de
mai
jos
este
prezetată
implementarea
algoritmului
„Descending

Demand”.


public

List<Designer> DescendingDemand(List<Designer> designers,

List<CommonArtistEntity> commonArtists)

{


foreach

(var artist

in

commonArtists)

{


var

firstDesigner = designers.First(x => x.Id == artist.FirstDesigner);


var

secondDesigner = designers.First(x => x.Id == artist.SecondDesigner);


int

smallestPartition = SmallestNoOfArtistsNeeded(firstDesigner, secondDesigner);


if

(firstDesigner.DateTimeShow.Date.Equals(secondDesigner.DateTimeShow.Date))

{


while

(PartitionTesting(firstDesigner, secondDesigner) != smallestPartition &&

firstDesigner.AllocatedArtists.Count != 0 &&

secondDesigner.AllocatedArtists.Count != 0)

{

RemoveArtistsPartition(firstDesigner);

RemoveArtistsPartition(secondDesigner);

}

}

65

secondDesigner.AllocatedArtists = alllocateNoOfNeededArtists(secondDesigner);

firstDesigner.AllocatedArtists = alllocateNoOfNeededArtists(firstDesigner);

}

return

designers;

}

Figura 32. Implementare – Descending Demand

Explica
ț
ia codului pentru metoda de implementare a algoritmului este următoarea:


La
fel
ca
în
cazul
algoritmului
anterior,
se
crează
o
metodă
cu
acela
ș
i
tip
de

returnare
ș
i
aceea
ș
i
parametrii
de
intrare,
doar

va
avea
numele
conform

algoritmului, respectiv „Descending Demand”;


Se
parcurge
lista
de
modele
comune,
care
con
ț
ine
to
ț
i
arti
ș
tii
care
se
regăsesc

în lista de preferate a designerilor;


Asemănător cu algoritmul de dinainte, se crează
ș
i se ini
ț
ializează seturile de

variabile: „firstDesigner”
ș
i „secondDesigner”, precum
ș
i

„firstDesignerArtistPosition ”, „secondDesignerArtistPosition”


Se
mai
creează
ș
i
o
a
treia
variabilă
(„smallestPartition”)
în
care
se
memorează

cel
mai
mic
numă
de
arti
ș
ti
favori
ț
i
dintre
cei
doi
designeri
care
sunt
la
rând.

Aceasta
se
ini
ț
ializează
cu
valoarea
rezultată
în
urma
apelării
metodei

„SmallestNoOfArtistsNeeded”,
care
returnează
numărul
de
care
avem
nevoie,

având parametrii de intrare cei doi designeri;


La
fel
se
verifică
dacă
ace
ș
ti
designeri
au
data
de
prezentare
a
evenimentului

în
aceea
ș
i
zi,
iar
dacă
nu
au,
atunci
se
sare
direct
către
finalul
metodei
în
care

se alocă fiecărui designer atâtea modele cât are nevoie pentru prezentare;


În
cazul
în
care
ace
ș
tia
au
prezentarea
în
aceea
ș
i
zi,
atunci
se
începe
alocarea

modelelor pe baza acestui algoritm;


Se
trece
printr-o
buclă
care
continuă
până
când
găse
ș
te
parti
ț
iile
de
modele

necesare
preferin
ț
elor
designerilor
ș
i
care
nu
se
suprapun,
apelând
metoda

„PartitionTesting”
care
urmează

fie
descrisă
în
cele
ce
urmează.
În
acela
ș
i

timp
se
asigură
(se
pune
condi
ț
ia
în
buclă)

mai
are
ce
modele

verifice,

deoarece
în
cadrul
buclei
se
apelează
o
metodă
care
ș
terge
setul
de
modele
de

la ambii designeri;

66

public


int

PartitionTesting(Designer firstDesigner, Designer secondDesigner)

{

int

partitionCount = 0;

int

smallestPartition = SmallestNoOfArtistsNeeded(firstDesigner, secondDesigner);

foreach

(var artist

in

firstDesigner.AllocatedArtists)

{

foreach

(var otherArtist

in

secondDesigner.AllocatedArtists)

{

if

(artist.ArtistId != otherArtist.ArtistId && partitionCount != smallestPartition)

{

partitionCount++;

}

else

{

return

partitionCount;

}

}

}

return

partitionCount;

}

Figura 33. Implementare – metoda „PartitionTesting”

În
cadrul
acestei
metode
se
elimiă
seturile/
parti
ț
iile
de
modele
de
care
nu
mai
avem

nevoie, pentru că se suprapun. Aceasta se efectuează astfel:


Se
declară
o
variabilă
„partitionCount”
ini
ț
ializată
cu
zero,
în
care
se
va
contoriza

numărul de modele care nu sunt comune din cadrul parti
ț
iei.


Se
declară
o
a
doua
variabilă
„smallestPartition”
în
care,
prin
apelarea
metodei

„SmallestNoOfArtistsNeeded”,
se
va
re
ț
ine
cel
mai
mic
număr
de
arti
ș
ti
de
care
are

nevoie unul dintre cei doi designeri;


Urmează
parcurgerea
modelelor
din
listele
celor
doi
designeri.
Se
verifică
dacă

modelele
sunt
diferite
ș
i
dacă
valoarea
din
„partitionCount”
este
diferită
de
valoarea

lui
„SmallestNoOfArtistsNeeded”,
iar
dacă
sunt
îndeplinite
aceste
condi
ț
ii,
se

incrementează
contorul
pentru
modelele
care
nu
sunt
comune.
Dacă
s-a
întâlnit

condi
ț
ia
ca
cel
pu
ț
in
două
modele

fie
la
fel
sau
s-a
ajuns
la
momentul
în
care
niciun

model
din
parti
ț
ie
nu
se
repetă,
atunci
se
va
ie
ș
i
direct
din
metodă
ș
i
se
va
returna

67

valoarea
variabilei
„partitionCount”,
cu
ajutorul
căreia
se
va
ș
tii
până
în
ce
statiu
s-a

ajuns;

4.1.3 Baza de date

Pentru
crearea
bazei
de
date
am
pornit
de
la
două
idei
de
tabele
principale,
una
pentru

arti
ș
ti
(modele)
ș
i
una
pentru
designeri,
pe
care
cu
ajutorul
frame work-ului,
.Net
Core
a
reu
ș
it

să le genereze automat în baza de date. Astfel am creat clasele: „Artist”
ș
i „Designer”.


public


class


Artist

: BaseEntity

{

public


string

Name {

get

;

set

; }

public


int

Height {

get

;

set

; }

public


int

Weight {

get

;

set

; }

public


int

BreastSize {

get

;

set

; }

public


int

WaistSize {

get

;

set

; }

public


int

HipsSize {

get

;

set

; }

public


string

EyesColor {

get

;

set

; }

public


string

HairColor {

get

;

set

; }

public


string

Facebook {

get

;

set

; }

public


string

Instagram {

get

;

set

; }

public


string

Description {

get

;

set

; }

public


string

Photo {

get

;

set

; }

public


string

Gender {

get

;

set

; }

public

IList<DesignerArtists> FavoriteForDesigners {

get

;

set

; }

}

Figura 34. Entitatea pentru un artist

Clasa
„Artist”
con
ț
ine
câmpurile
necesare
pentru
detaliile
modelelor
(nume,
prenume,

culoarea
părului
etc.)
ș
i
o
listă
de
tipul
unei
alte
clase
(„

DesignerArtists

”)
pentru
a
face
legătura

dintre
cele
două
clase.
În
această
listă
se
vor
re
ț
ine
designerii
pentru
care
este
favorit
modelul

respectiv.


public


class


Designer

: BaseEntity

{

public


string

Name {

get

;

set

; }

public


string

Surname {

get

;

set

; }

68

public


string

Mail {

get

;

set

; }

public


int

nrOfArtistsNeeded {

get

;

set

; }

public

DateTime DateTimeShow {

get

;

set

; }

public

String LocationShow {

get

;

set

; }

public

List<DesignerArtists> FavoriteArtists {

get

;

set

; } =

new

List<DesignerArtists>();

[NotMapped]

public

List<DesignerArtists> AllocatedArtists {

get

;

set

; }

[NotMapped]

public


int

Score {

get

;

set

; }

}

Figura 35. Entitatea pentru un designer

Această
clasă
con
ț
ine,
pe
lângă
datele
necesare
designerului,
două
liste
de
tipul
clasei



DesignerArtists

”,
la
fel
ca
în
figura
anterioară,
în
care
se
vor
re
ț
ine
arti
ș
tii
prefera
ț
i
de

designeri
ș
i arti
ș
tii aloca
ț
i în urma algoritmilor aplica
ț
i.

Ambele
clase
mo
ș
tenesc
clasa
BaseEntity,
în
care
se
află
câmpurile
de
id,
care
se

generează în mod unic
ș
i automat,
ș
i data înregistrării unei entită
ț
i.

public


class


BaseEntity

{

public

Guid Id {

get

;

set

; }

public

DateTime DateCreated {

get

;

set

; }

}

Figura 36. Entitatea de bază

În
cadrul
rezultatelor
algoritmilor
executa
ț
i,
ace
ș
tia
re
ț
in
următoarele
proprietă
ț
i:
lista

de
designeri
împreună
cu
tot
ce
ț
ine
de
ei,
scorul
pentru
fiecare
algoritm
ș
i
timpul
în
care
s-au

executat ace
ș
tia.


public


class


AlgorithmResult

{

public

List<Designer> Designers {

get

;

set

; }

public


int

Score {

get

;

set

; }

public


double

TimeExecuted {

get

;

set

; }

}


Figura 37. Entitatea rezultate algoritm

69

To
ț
i
arti
ș
tii
comuni
designerilor
în
cauză
se
re
ț
in
prin
intermediul
id-urilor
lor,
salva
ț
i

într-o
clasă.
Arti
ș
tii
în
cauză
sunt
doi
care
prezintă
în
aceea
ș
i
zi
ș
i
care
doresc
acelea
ș
i

modele,
iar
pentru
aceasta
li
se
re
ț
in
ș
i
id-urile
lor
în
acela
ș
i
loc
în
care
e
află
ș
i
id-urile

modelelor comune.


public


class


CommonArtistEntity

{

public

Guid FirstDesigner {

get

;

set

; }

public

Guid SecondDesigner {

get

;

set

; }

public

Guid ArtistId {

get

;

set

; }

}


Figura 38. Entitatea arti
ș
ti comuni

4.2 Descrierea aplica
ț
iei web

Aplica
ț
ia
web
are
scopul
de
a
aloca
modelele
evenimentelor
corespunzător
cerin
ț
elor

designerilor
ș
i
în
func
ț
ie
de
disponibilitatea
acestora.
De
asemenea,
aplica
ț
ia
oferă

posibilitatea designerilor de a-
ș
i selecta modelele preferate.

Prin
navigarea
în
fereastra
„Fashion
models”
se
poate
observa
listat
toate
modele

înscrise în platformă, conform imaginii de mai jos.

Figura 39. Fereastra „Fa
ș
hion models”

70

În
partea
de
sus
a
paginii
este
afi
ș
at
un
număr
care
reprezintă
totalul
de
modele

afi
ș
ate.
În
această
pagin ă
se
mai
pot
observa,
pe
lângă
pozele
de
profil,
câteva
detalii

importante
de-a
lor
precum:
înăl
ț
imea,
greutatea
ș
i
dimensiunile
corporale.
Mai
multe
detalii

despre aceasta vor fi afi
ș
ate dacă se va da click pe numele lor.

De
asemenea,
această
fereastră
prezintă
ș
i
posibilitatea
de
a
actualiza
ș
i
de
a
ș
terge

modele, despre care voi vorbi în continuare.

O
dată
ce
s-a
dat
click
pe
numele
modelelor,
se
pot
observa
detaliile
despre
acestea,

a
ș
a cum este ilustrat în im aginea de mai jos.

Figura 40. Detalii despre model

În
această
imagine
este
reprezentat
un
tabel
cu
datele
modelului.
Prin
iconi
ț
ele
de

lângă
numele
acestora
se
pot
accesa
paginile
acestora
de
Facebook
ș
i
de
Instagram
în
urma

cărora, designerul î
ș
i poa te face o imagine mai amplă asupra modelului.

În
partea
dreaptă
a
paginii
este
afi
ș
ată
o
imagine
de
profil
prin
care
aceasta
dore
ș
te

î
ș
i eviden
ț
ieze cât mai bine trăsăturile.

Pentru
încărcarea
acestei
imagini,
este
nevoie
ca
această
ac
ț
iune

se
facă
atunci
când

se
adaugă
un
model
nou
sau
chiar
dacă
modelul
este
deja
înregistrat
în
baza
de
date,
se
poate

executa
o
actualizare
a
datelor.
În
acest
sens,
modelul
va
adăuga
o
rută
de
pe
web

reprezentată de imaginea care se dore
ș
te.

71

În
imaginea
de
mai
jos
este
reprezentată
adăugarea
unui
model
nou
în
baza
de
date.

La
această
pagină
se
ajunge
printr-un
click
de
pe
fereastra
„Fashion
models”
explicată
mai

sus, pe iconi
ț
a de plus din col
ț
ul din dreapta.

Figura 41. Adăugarea unui nou model

De
asemena,
actualizarea
modelului
se
face
tot
printr-un
click,
de
pe
aceea
ș
i
pagină,

doar

pe
o
altă
iconi
ț
ă.
Fiecare
model
afi
ș
at
are
în
dreptul
său
o
iconi
ț
ă
prin
care
se
ajunge

la actualizarea ei. În imaginea de mai jos voi prezenta această fereastră.

Figura 42. Editarea unui model deja existent

72

În
cazul
imaginii
de
mai
sus,
actualizarea
(editarea)
persoanei
se
face
asemănător
cu
cea
în

cazul
în
care
se
dore
ș
te
adăugarea
unui
model
nou.
Diferen
ț
a
este

nu
mai
sunt
câmpuri

sugestive
pentru
completare,
ci
sunt
câmpuri
completate
deja
cu
datele
deja
existente
ale

modelului
respectiv.
Modificarea
acestor
date
se
poate
efectua
simplu
prin
supra
scrierea

noilor date.

Figura 43 Salvarea noilor date

Pentru
a
salva
noile
date,
se
va
da
click
pe
butonul
de
„save”,
amplasat
la
sfâr
ș
itul

câmpurilor
de
detalii.
Odată
ce
s-a
dat
click
pe
acest
buton,
datele
vor
fi
direct
salvate
în
baza

de date.

Ș
tergea
unui
model
se
face
prin
accesarea
butonului
de
ș
tergere,
de
lângă
cel
de

actualizare.
Butonul
este
reprezentat
printr-o
iconi
ț
ă
în
formă
de
co
ș
de
gunoi.
O
dată
ce
s-a

dat click pe acesta, modelul nu va mai apărea
ș
i va fi
ș
ters din baza de date.

Pentru
accesul
la
designerii
din
cadrul
festivalului,
se
va
accesa
butonul
„Designers”

din dashboard (tablou de bord).

73

Figura 44. Fereastra „Designers”

În
această
fereastră
se
observă
artistele
(modele)
preferate
de
designeri.
Ace
ș
tia
ș
i-au

selectat
un
număr
mai
mare
de
modele
decât
au
ei
nevoie,
pentru
a
se
asigura

în
urma

algoritmului

primească
numărul
necesar
de
modele.
Numărul
modele
necesar
fiecărui

designer
este
reprezentat
în
câmpul
„Needed”
(necesare).
În
partea
dreaptă
a
paginii
este

reprezentată alocarea modelelor pentru fiecare designer în parte.

Un
detaliu
important
pe
care
îl
con
ț
ine
această
pagină
este
afi
ș
area
datei
ș
i
a
orei
în

care
urmează

se
desfă
ș
oare
prezentarea
de
modă.
Acest
detaliu
este
unul
foarte
important,

pentru

prezentările
de
modă
care
urmează

se
desfă
ș
oare
în
aceea
ș
i
zi
cu
alte
prezentări,

vor
avea
de
suferit
modificări
în
ceea
ce
ț
ine
repartizarea
modelelor.
În
acest
caz
se
va
intra
în

algoritmul
creat
din
spatele
aplica
ț
iei.
Cu
toate
acestea,
repartizarea
arti
ș
tilor
se
va
face

dinamic, apărând to
ț
i deo dată, fără să afecteze în vreun fel utilizatorul.

74

Figura 45. Fereastra pentru actualizarea designerului

Actualizarea
designerului
se
face
asemănător
cu
cea
a
modelelor.
O
iconi
ț
ă

corespunzătoare
va
fi
afi
ș
ată
în
fereastra
„Designeri”
prezentată
mai
sus.
Principala
diferen
ț
ă

dintre
model
ș
i
designer
este

designerul
are
afi
ș
ată
ș
i
o
listă
prin
care
sunt
reda
ț
i
arti
ș
tii

favori
ț
i
de
el,
pe
care
i-a
selectat
conform
ferestrei
de
mai
jos.
Navigarea
către
selectarea

acestora se face accesând butonul de actualizare din partea stângă a imaginii.

Figura 46. Selectarea modelelor de către designer

75

Selectarea
artistelor
dorite
se
face
prin
bifarea
căsu
ț
ei
din
cadranul
artistei.
Modelelor

care
au
fost
selectate
deja,
le
rămâne
bifată
căsu
ț
a,
iar
celorlalte
le
rămâne
goală
o
dată
ce
s-a

ajuns la această pagină de la ruta designerului selectat.

De
asemenea,
ordinea
modelelor
este
foarte
importantă
în
selectarea
lor.
Aceasta

reprezintă
cât
de
preferată
este
o
artistă.
Punerea
acestora
în
ordinea
dorită
se
efectuează
prin

mecanismul
trage
ș
i
plasează
(drag
and
drop)
în
care
designerul
ț
ine
apăsat
pe
modelul
dorit

ș
i în a
ș
ează în rândul dorit.

Salvarea
acestor
date
se
efectuează
prin
click-ul
„save”
plasat
la
sfâr
ș
itul
tuturor

modelelor.

Figura 47. Salvarea modelelor selectate

Această
salvare
permite
actualizarea
directă
ș
i
în
baza
de
date,
ceea
ce
înseamnă

noua modificare nu v-a necesita timp de a
ș
teptare.

Fereastra
de
diagrame
din
următoarea
imagine
redă
un
grafic
reprezentat
de
scorul

celor doi algoritmi implementa
ț
i (Adjusted Winner
ș
i Descending Demand).

76

Figura 48. Fereastra „Charts”

Atunci
când
se
trece
cu
mouse-ul
peste
un
bloc,
se
indică
un
număr
care
reprezintă
scorul

algoritmului
respectiv.
Algoritmul
cel
mai
bun
este
sugerat
de
blocul
care
are
scorul
cel
mai

mare. În cazul nostru, cel mai favorabil algoritm este algoritmul „Adjuste Winner”.

În
partea
de
jos
a
imaginii
sunt
descri
ș
i
algoritmii
împreună
cu
conceptul
de

implementare al acestora.

4.2.1 Implementarea aplica
ț
iei client

În
continuare
voi
prezenta
modul
în
care
am
creat
un
data
serviciu
pentru
a
consuma

un API-ul ASP.NET Core REST cu modul Http Angular.

Configura
ț
ia

Am
ales
fi
ș
ierul

http-service.ts
pentru
a
scrie
configura
ț
ia.
Dacă
se
va
schimba
ceva
în

acest
loc,
de
exemplu
o
versiune
api
care
este
stocată
în
URL
sau
în
punctul
final/
server,

acele modificări se pot face aici.

import

{ Injectable }

from


'@angular/core'

;

import

{ HttpClient, HttpHeaders }

from


'@angular/common/http'

;

import

{ map }

from


'rxjs/operators'

;

@Injectable()

77

export


class

HttpService {

constructor

(

public

httpClient: HttpClient) {

}

BASE_URL =

'

https://localhost:44304

'

;

FASHION_MODELS =

this

.BASE_URL +

'/api/artists'

;

DESIGNERS =

this

.BASE_URL +

'/api/designers'

;

ALLOCATED_MODELS =

this

.BASE_URL +

'/api/resourceallocation/adjusted-winner'

;

DESCENDING_DEMAND =

this

.BASE_URL +

'/api/resourceallocation/descending-demand'

;

ADJUSTED_WINNER =

this

.BASE_URL +

'/api/resourceallocation/adjusted-winner'

;

contentHeader: HttpHeaders =

new

HttpHeaders({


'Content-Type'

:

'application/json'

,


'Accept'

:

'application/json'

,


'Cache-Control'

:

'no-cache'

,


'Access-Control-Allow-Origin'

:

'http://localhost:4200'

});

public

saveDesigner(designer: any): any {


return


this

.httpClient.put(

this

.DESIGNERS, designer, {headers:

this

.contentHeader});

}

public

getFashionModels() {


return


this

.httpClient.get(

this

.FASHION_MODELS, {headers:

this

.contentHeader});

}

public

getFashionModelById(id) {


return


this

.httpClient.get(

this

.FASHION_MODELS +

'/'

+ id, {headers:

this

.contentHeader});

}

public

saveFashionModel(fashionModel) {


return


this

.httpClient.put(

this

.FASHION_MODELS, fashionModel, {headers:

this

.contentHeader});

}


public

updateFashionModel(fashionModel) {


return


this

.httpClient.patch(

this

.FASHION_MODELS, fashionModel, {headers:

this

.contentHeader});

}

public

deleteFashionModel(id) {


return


this

.httpClient.delete(

this

.FASHION_MODELS +

'/'

+ id, {headers:

this

.contentHeader});

}

78

public

getDesigners() {


return


this

.httpClient.get(

this

.DESIGNERS, {headers:

this

.contentHeader});

}

public

getDesignerById(id) {


return


this

.httpClient.get(

this

.DESIGNERS +

'/'

+ id, {headers:

this

.contentHeader});

}

public

updateDesigner(designer) {


return


this

.httpClient.patch(

this

.DESIGNERS, designer, {headers:

this

.contentHeader});

}

public

deleteDesigner(id) {


return


this

.httpClient.delete(

this

.DESIGNERS +

'/'

+ id, {headers:

this

.contentHeader});

}

public

navigateToSelectModels(id) {


return


this

.httpClient.post(

this

.DESIGNERS +

'/'

+ id, {headers:

this

.contentHeader});

}

public

setFavoriteArtists(id, favoriteArtists) {


return

this

.httpClient.post(

this

.DESIGNERS
+

'/'
+
id
+

'/set-favourite-models'

,
favoriteArtists,

{headers:

this

.contentHeader});

}

public

getAllocatedModels() {


return


this

.httpClient.get(

this

.ALLOCATED_MODELS, {headers:

this

.contentHeader});

}

public

getAdjustedWinnerEvalutation() {


return


this

.httpClient.get(

this

.ADJUSTED_WINNER, {headers:

this

.contentHeader});

}

public

getDescendingDemandEvalutation() {


return


this

.httpClient.get(

this

.DESCENDING_DEMAND, {headers:

this

.contentHeader});

}

}

Figura 49. Configurare conexiune client – server

79

În
codul
de
mai
sus
am
am
pregătit
toate
solicitările
pentru
a
fi
gata
atunci
când

intervine
o
cerere,
un
request
de
a
fi
gata
de
fiecare
dată
când
apelăm
o
func
ț
ie.
Am
importat

următoarele
librăriile
Injectabil,
necesar
pentru
crearea
serviciului
ș
i
HttpClient,
pentru

facilitarea
procesului
de
comunicare.
Am
injectat
modului
HttpClient
in
parametrii

constructorului.
Am
declarat
variabilele
pentru
endpoint-urile
RESTful
API
ș
i
head-urile

Http,
apoi
am
adăugat
func
ț
iile
pentru
toate
endpoint-urile
RESTful
API
CRUD
din
API.
Am

instan
ț
iat variabila http pe ntru a fi de tip httpClient, a
ș
a cum se poate observa în constructor.

Pentru
getFashionModels
sau
getDesigners
ob
ț
inem
toate
înregistrările
găsite
în
baza

de
date
pe
care
o
apelăm
prin
metoda
get
al
obiectului
http
ș
i
îi
transmitem
ca
parametru

adresa
URL.
Diferen
ț
a
la
metodele
getFashionModelById
ș
i
getDesignerById
este

la

acestea
trecem
un
parametru
id
ca
parametru
metodei
care
apoi
apelată.
Acest
parametru

reprezintă
antetul
cererii
care
specifică
tipul
de
con
ț
inut
care
este
transmis.
Prin
metodele
de

addDesigner,
addFashionModel
se
adaugă
designeri
ș
i
modele
în
baza
de
date.
Metodele

pentru
actualizarea
acestora
sunt
date
de
metodele
care
con
ț
in
antetul
update.
Prin
invocarea

metodei
delete
se
ș
terg
obiectele
http
(designerii
ș
i
modele).
Pentru
executarea
algoritmilor

dori
ț
i,
respectiv
Adjuste d
Winner
ș
i
Descending
Demand
sunt
metode
separate,
deoarece

ace
ș
tia
pot
da
rezultate
diferite
ș
i
în
majoritatea
cazurile
a
ș
a
se
întâmplă.
Prin
metoda

setFavoriteArtists
se
salvează
arti
ș
tii
(modelele)
favori
ț
i
pentru
fiecare
designer
în
parte,
dând

ca
parametru
id-ul
acestora
în
metodă.
Prin
metoda
navigateToSelectedModels
se
afi
ș
ează

modele pe care le-a selectat designerul respectiv.

Aceste
metode
au
fost
utilizate
în
fi
ș
ierele
component.ts
ș
i
au
fost
scrise
în
limbajul

type
script,
la
fel
ca
cele
de
mai
sus.
Un
exemplu
de
utilizare
pentru
accesarea
modelelor
este

reprezentat în figura de mai jos.


export


class

FashionModelsListComponent

implements

OnInit {

public

fashionModels: any;

constructor

(

public

httpService: HttpService,

public

router: Router) {

}

ngOnInit() {


this

.httpService.getFashionModels().subscribe(response

=>

{


this

.fashionModels = response;

});

}

navigateToFashionModels() {

80


this

.router.navigate([

'/fashion-models'

]);

}

navigateToAddNewFashionModel() {


this

.router.navigate([

'/fashion-models/add'

]);

}

navigateToFashionModelDetails(id) {


this

.router.navigate([

'/fashion-models/details'

], { queryParams: { id: id } });

}

navigateToFashionModelEdit(id) {


this

.router.navigate([

'/fashion-models/edit'

], { queryParams: { id: id } });

}

navigateToFashionModelDelete(id) {


if

(confirm(

'Are you sure to delete this fashion model?'

) ===

true

) {


this

.httpService.deleteFashionModel(id)

.subscribe(result

=>

{


this

.httpService.getFashionModels().subscribe(response

=>

{

this

.fashionModels = response; });

});

}

}

}


Figura 50. Accesarea modelelor

Prin
această
clasă
prima
dată
sunt
afi
ș
ate
toate
modelele
pe
ecran
prin
ngOnInit
care

este
un
hook
life
cycle
(cârlig
ciclu
de
via
ț
ă).
Acesta
este
apelat
de
Angular
pentru
a
indica

Angular
a
terminat
crearea
componentei.
În
continuare
sunt
prezentate
metodele
necesare

pentru
afi
ș
area
detaliilor
modelelor,
pentru
ș
tergerea,
actualizarea
ș
i
adăugarea
acestora.
La

metoda
de
ș
tergere,
se
observă
ca
obiectul
este
ș
ters
doar
dacă
s-a
răspuns
pozitiv
la

întrebarea pentru
ș
tergere a acestuia.

Metodele din această clasă sunt folosite în codul html astfel:

<div


class

=

"row"

>

<div


class

=

"col-sm-4"


*ngFor

=

"let fashionModel of fashionModels; index as i"

>


<div


class

=

"card bg-light mb-3"

>


<div


class

=

"card-header"

>

<h4


class

=

"card-title"

>

<span


(click)

=

"navigateToFashionModelDetails(fashionModel.id)"


class

=

"pointer"

>

{{fashionModel.name}}

</span>

<i


class

=

"fa fa-trash btn float-right"

(click)

=

"navigateToFashionModelDelete(fashionModel.id)"

>

81

</i>

&nbsp;

<i


class

=

"fa fa-edit btn float-right"

(click)

=

"navigateToFashionModelEdit(fashionModel.id)"

>

</i>

&nbsp;

</h4>

<p


class

=

"card-text"

>

Height: {{fashionModel.height}},

Breast: {{fashionModel.breastSize}},

Waist: {{fashionModel.waistSize}},

Hips: {{fashionModel.hipsSize}}

</p>

<img


src

=

"{{fashionModel.photo ? fashionModel.photo :

'assets/images/fashionmodelplaceholder.png'}}"


class

=

"model-image"

/>


</div>


</div>

</div>

</div>


Figura 51. Afi
ș
area modelelor

Aici
se
face
apel
la
metodele
pentru
afi
ș
area
modelelor.
Detaliile
despre
acestea,
cum

ar
fi
măsurile
lor
se
accesează
prin
obiectul
fashionModel,
de
exemplu
fashionModel.height,

pentru
accesa
înăl
ț
imea
acestuia.
În
cadrul
acestei
pagini,
se
afi
ș
ează
toate
modelele
prin

parcurgerea
listei.
În
cazul
în
care
un
model
nu
are
imagine
de
profil,
ii
se
va
atribui
una
în

mod implicit.

Din
această
pagină
se
poate
face
apel
către
alte
pagini,
prin
accesarea
diferitelor

butoane,
cum
ar
fi
butonul
de
editare.
Atunci
când
se
va
da
click
pe
acesta,
se
va
face
un
apel

către
respectiva
metodă
din
component.ts
descrisă
mai
sus,
care
accesează
fi
ș
ierul
de
rutare

dat de figura de mai jos.

import

{ NgModule }

from


'@angular/core'

;

import

{ Routes, RouterModule }

from


'@angular/router'

;

import

{ FashionModelsListComponent }

from

'./fashion-models-list.component'

;

import

{ FashionModelsAddComponent }

from

'./fashion-models-add.component'

;

import

{ FashionModelsDetailsComponent }

from

'./fashion-models-details.component'

;

82

import

{ FashionModelsEditComponent }

from

'./fashion-models-edit.component'

;

import

{ FashionModelsDeleteComponent }

from

'./fashion-models-delete.component'

;

const

routes: Routes = [

{path:

''

, component: FashionModelsListComponent},

{path:

'add'

, component: FashionModelsAddComponent},

{path:

'details'

, component: FashionModelsDetailsComponent},

{path:

'edit'

, component: FashionModelsEditComponent},

{path:

'delete'

, component: FashionModelsDeleteComponent}

];

@NgModule({

imports: [RouterModule.forChild(routes)],

exports: [RouterModule]

})

export


class

FashionModelsRoutingModule {}


Figura 51. Fi
ș
ierul pentru rutare

83

5. Concluzii
ș
i dezvoltări ulterioare

5.1 Concluzii

Aplica
ț
ia
de
alocare
a
modelelor
în
cadrul
festivalelor
de
modă
a
reprezentat
pentru
mine
o

provocare
din
punct
de
vedere
al
cunoa
ș
terii
tehnologiei.
Înainte
de
a
începe
munca,
nu

aveam
experien
ț
a
de
construi
o
aplica
ț
ie
client

server
în
cadrul
unui
site
web
folosind
Visual

Studio
ș
i
Angular.
Pentru
mine,
cea
mai
mare
provocare
a
fost


familiarizez
cu

Angular-ul.
Un
framework
foarte
util
ș
i
important
în
dezvoltarea
aplica
ț
iilor
client,
pe
care

am ajuns să îl apreciez pentru func
ț
ionalită
ț
ile sale multiple.

Una
dintre
motiva
ț
iile
pentru
care
am
ales

creez
această
aplica
ț
ie
este
datorită
necesită
ț
ii

unei
astfel
de
aplica
ț
ie
în
cadrul
festivalelor.
Pentru
a
fi
sigură
ca
aceasta
este
folositoare,
am

discutat
cu

ț
iva
direct ori
de
festivale,
iar
ace
ș
tia
s-au
arătat
încânta
ț
i,
dorind

testeze

aplica
ț
ia chiar la următor ul eveniment.

Atunci
când
am
început

lucrez
la
aplica
ț
ie,
mi-am
propus
ca
aceasta

con
ț
ină
următoarele

fun
ț
ionalită
ț
i:


adăugarea de noi modele
ș
i designeri


modificarea detaliilor modelelor
ș
i designerilor deja existen
ț
i


posibilitatea
ș
tergerii acestora din baza de date


selectarea unei liste de modele preferate pentru fiecare designer


alocarea
modelelor
designerilor
în
func
ț
ie
de
preferin
ț
elor
acestora
ș
i
de

disponibilitatea modelelor, într-un mod cât mai corect
ș
i egal

Rezultatul
final
al
lucrării
s-a
transpus
într-o
aplica
ț
ie
care
îndepline
ș
te
toate

obiectivele men
ț
ionate m ai sus.

5.1 Compara
ț
ii între algoritmi

Cei
doi
algoritmi
descri
ș
i
mai
sus
„Adjusted
Winner”
ș
i
„Descending
Demand”
au

fost
ambii
implementa
ț
i
în
cadrul
aplica
ț
iei,
dar
cu
toate
acestea,
unul
singur
a
fost
ales

pentru a afi
ș
a alocara de m odele, rezultatele lor fiind diferite.

Algoritmul
pe
care
l-am
ales
este
„Adjusted
Winner”.
Acesta
s-a
dovedit
a
avea
cel

mai
bun
scor.
Din
punct
de
vedere
al
timpului
de
executare,
algoritmul
„Descending

84

Demand”
este
mai
rapid
decât
celălalt,
dar
aceste
diferen
ț
e
sunt
mult
prea
mici
ș
i
se
pot
vedea

doar
la
mii
de
înregistrări
în
baza
de
date,
motiv
pentru
care
„Ajusted
Winner”
rămâne

algoritmul „câ
ș
tigător”.

5.1 Dezvoltări ulterioare

În
cadrul
concursului
„Innovation
Labs”,
din
luna
martie,
la
care
am
participat
pentru

început
cu
această
aplica
ț
ie,
ideea
mea
a
fost
bine
văzută
de
juriu.
Astfel,
membrii
juriului

m-au
încurajat
spre
a
dezvolta
aplica
ț
ia
pentru
a
fi
folosită
ș
i
în
alte
scopuri.
Ideea
principală

a
constat
într-o
platformă
de
promovare
a
modelelor,
prin
care
mai
multe
persoane
care
au

nevoie
de
modele
pentru
diverse
reclame
publicitare,
prezentări
de
modă
în
afara
festivalelor,

fotografii pentru promovarea de produse etc., le pot găsi mai u
ș
or.

Noul
sistem
la
care
am
încercat

lucrez,
dar
pe
care
nu
am
reu
ș
it

il
aplic
încă,
îl

voi
explica
în
cele
ce
urmează.
Modelele
î
ș
i
fac
cont
ș
i
î
ș
i
încarcă
poze,
pentru
a
fi
găsite
mai

u
ș
or
de
poten
ț
ialii
clien
ț
i.
Acestea
vor
prezenta
ș
i
un
pre
ț
de
la
care
încep

lucreze,
la
care

noi
vom
adăuga
un
comision
care
v-a
fi
plătit
de
clien
ț
i,
atunci
când
doresc

rezerve
un

model.
De
asemenea,
modelele
au
posibilitatea
de
a
fi
afi
ș
ate
primele
în
rezultatele
unei

căutări
pentru
a
fi
promovate
ș
i
mai
mult,
în
schimbul
unei
sume
de
bani.
Acest
sistem

seamănă
cu
celebrul
sistem
de
închirieri
de
locuin
ț
e
al
site-ului


www.airbnb.com

”.

Avantajul
iedei
aplica
ț
iei
este

aceasta
vine
la
pachet
cu
sistemul
de
alocare
a
modelelor
în

cadrul festivalelor de modă, ceea ce reprezintă un plus fa
ț
ă de ceea ce este deja pe pia
ț
ă.

85

Abrevieri

ANSI

American National Standards

Institute

JS

Java Script

API

Application Programming

Interface

LINQ

Language Integrated

Query

CEO

Chief Executive Officer

MVC

Model View Controller

CLI

Comand Line Interface

OOD

Object Orientated design

CLR

Common Language Runtime

OOP

Object Oriented

Programming

CPU

Central Processing Unit

REST

Representational State

Transfer

CRUD

Create, Read, Update, Delete

SOLID

Single responsability

Open–closed principle

Liskov substitution

Interface segregation

Dependency inversion

CSS

Cascading Style Sheets

SPA

Single Page Applications

HTML

Hypertext Markup Language

SQL

Structured Query

Language

HTTP

Hypertext Transfer Protocol

TCP

Ttransmission Control

Protocol

ID

Database Identifier

TS

Type Script

IDE

Integrated Development

Enviroment

UI

User Interface

IL

International Language

URI

Uniform Resource

Identifier

JIT

Just In Time

URL

Uniform Resource

Locator

86

Figuri

Figura 1. Aplica
ț
ie

server-client

8

Figura 13. Clasa Main

35

Figura 2. Exemplu de

legătură unu la mul
ț
i

11

Figura 14. Clasa

Designer din stratul

Domeniu

35

Figura 3. Exemplu de

legătură mul
ț
i-la-mul
ț
i

12

Figura 15. Clasa Artist

din stratul Domeniu

36

Figura.4. Exemplu de

legătură unu-la-unu

13


Figura 16. Clasa

BaseEntity din stratul

Domeniu

36

Figura 5. Abordarea

Code-First

15

Figura 17. Clasa

DesignerArtists din

stratul Domeniu

37

Figura 6. Opera
ț
iile

CRUD

17


Figura 18. Clasa

AlgorithmResult din

stratul Domeniu

37

Figura 7: Arborele

genealogic C#

20

Figura 19. Clasa

CommonArtistEntity din

stratul Domeniu

37

Figura 8. Componentele

Angular

27


Figura 20. Ruta

controller-ului

38

Figura 9. Componentele

TypeScript

29


Figura 21. Ruta

controller-ului

40

Figura 10. Arhitectura

sistemului

33

Figura 22. Clasa

Startup

42

Figura 11. Aplica
ț
ia

server

33

Figura 23.

Legarea serviciului

nostru de clase necesare

43

Figura 12. Designe-ul

aplica
ț
iei WebApi

34

Figura 24. Clasa

Designer

45

87

Figura 25. Endpoint

pentru afi
ș
area arti
ș
tilor

46

Figura 39. Fereastra

„Fa
ș
hion models”

65

Figura 26. Afi
ș
area

arti
ș
tilor cu PostMan

47

Figura 41. Adăugarea

unui nou model

66

Figura 27. Scenarii de

utilizare

48

Figura 42. Editarea unui

model deja existent

66

Figura 28. Schemă

logică – metoda de

alocar

51

Figura 43. Salvarea

noilor date

67

Figura 29. Schemă

logică – algoritmul

„Adjusted Winner”

53

Figura 44. Fereastra

„Designers”

68

Figura 30. Implementare

– Adjusted Winner

55

Figura 45. Fereastra

pentru actualizarea

designerului

69

Figura 31. Schemă

logică – algoritmul

„Descending Demand”

58

Figura 46. Selectarea

modelelor de către

designer

69

Figura 32. Implementare

– Descending Demand

60

Figura 47. Salvarea

modelelor selectate

70

Figura 33. Implementare

– metoda

„PartitionTesting”

61

Figura 48. Fereastra

„Charts”

71

Figura 34. Entitatea

pentru un artist

62

Figura 49. Configurare

conexiune client – server

72

Figura 35. Entitatea

pentru un designer

63


Figura 50. Accesarea

modelelor

75

Figura 36. Entitatea de

bază

63

Figura 51.

Afi
ș
area modelelor

76

Figura 37.

Entitatea rezultate

algoritm

63


Figura 51.

Fi
ș
ierul pentru rutare

77


Figura 38.

Entitatea arti
ș
ti comuni

64

88

Bibliografie

[1] Back-End Architecture – Code Academy,

https://www.codecademy.com/articles/back-end-architecture

[2] Microsoft SQL Server – Wikipedia,

https://ro.wikipedia.org/wiki/Microsoft_SQL_Server

[3] Entity Framework – Microsoft docs,

https://docs.microsoft.com/en-us/previous-versions/gg696172(v=vs.100)

[4] Entity Framework – TutorialPoint,

https://www.tutorialspoint.com/entity_framework/entity_framework_overview.htm

[5] Domain-Driven Design – Wikipedia,

https://en.wikipedia.org/wiki/Domain-driven_design

[6] Entity Framework – Entity Framework Tutorial,

http://www.entityframeworktutorial.net/code-first/what-is-code-first.aspx

[7] ASP .Net Introduction – TutorialsPoint,

https://www.tutorialspoint.com/asp.net/asp.net_introduction.htm

[8] ASP .Net Core Web API Attributes – Dot Net Curry,

https://www.dotnetcurry.com/aspnet/1390/aspnet-core-web-api-attribute

[9] „Fundamentals of Computer Programming with C#”, Svetlin Nakov & Co, 2013

[10] Articol Unchiul Bob,

http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod

[11] Angular – Wikipedia,

https://en.wikipedia.org/wiki/Angular_(web_framework)

[12] TypeScript – TutorialsPoint

https://www.tutorialspoint.com/typescript/typescript_overview.htm

[13] HTML – TutorialsPoint

https://www.tutorialspoint.com/html/html_overview.htm

[14] CSS – TutorialsPoint

https://www.tutorialspoint.com/css/what_is_css.htm

[15] „Computer Supported Collaborative Decision-Making”, Florin Gheorghe Filip,

Constantin-Bălă Zamfirescu, Cristian Ciurea

[16] „Strategic Behaviour when Allocating Indivisible Goods Sequentially”, Thomas

Kalinowski, Nina Narodytska and Toby Walsh, Lirong Xia

[17] Adjusted Winner procedure,

http://math.uga.edu/~pbergonio/Su14/DM/13A.pdf

89

Similar Posts