book-openFakeDatabase și Repository Layer

Ce este FakeDatabase

FakeDatabase este, în exemplul nostru, o clasă statică care simulează o sursă de date externă (o bază de date, un fișier, un serviciu web). Conține o singură colecție statică de cărți și nimic altceva. Nu are logică, nu are metode, nu are validare. Este pur și simplu un container de date accesibil global.

static class FakeDatabase
{
    // Lista statica — exista o singura copie in toata aplicatia,
    // indiferent de cate obiecte sau clase o acceseaza
    public static List<Carte> Carti = new List<Carte>
    {
        new Carte { Titlu = "Clean Code", Autor = "Robert Martin",
                    AnAparitie = 2008, Gen = GenCarte.Tehnic, Pret = 89.99m },
        new Carte { Titlu = "Dune", Autor = "Frank Herbert",
                    AnAparitie = 1965, Gen = GenCarte.StiintaFictiune, Pret = 49.99m },
        new Carte { Titlu = "Sapiens", Autor = "Yuval Noah Harari",
                    AnAparitie = 2011, Gen = GenCarte.Biografie, Pret = 65.00m }
    };
}

Cuvântul cheie static pe clasă înseamnă că nu poate fi instanțiată, ci există automat la pornirea aplicației și trăiește pe toată durata ei. Cuvântul cheie static pe proprietatea Carti înseamnă că lista aparține clasei, nu unui obiect, și că există o singură copie a ei în memorie.

Această distincție este importantă: nu contează de câte ori și de unde accesezi FakeDatabase.Carti — vorbești mereu despre aceeași listă, nu despre copii separate.

De ce FakeDatabase și nu datele direct în repository

Ar putea părea că e mai simplu să pui lista de cărți direct în CarteRepository:

Problema cu această abordare este că amestecă două responsabilități distincte în aceeași clasă: stocarea datelor și accesul la date. Repository-ul ar juca simultan rolul de sursă de date și de intermediar.

Consecința practică: dacă mai târziu vrei să înlocuiești lista din memorie cu o bază de date reală, trebuie să rescrii CarteRepository în totalitate, pentru că logica de acces (metodele GetAll, Add etc.) și datele sunt împletite.

Separând FakeDatabase de CarteRepository, fiecare are un singur rol:

  • FakeDatabase știe unde trăiesc datele

  • CarteRepository știe cum să opereze pe ele

La înlocuirea sursei de date, schimbi doar FakeDatabase sau modul în care CarteRepository o accesează, iar structura metodelor CRUD rămâne identică.

Structura repository-ului

CarteRepository nu deține nicio colecție proprie. Toate operațiile sale accesează FakeDatabase.Carti direct:

Toate operațiile vorbesc explicit cu FakeDatabase.Carti. Nimeni care citește CarteRepository nu poate greși de unde vin datele.

De ce GetAll() returnează o copie

GetAll() returnează new List<Carte>(FakeDatabase.Carti), nu FakeDatabase.Carti direct. Motivul este același ca și în cazul în care datele ar fi deținute de repository: codul din exterior nu trebuie să poată modifica colecția sursă ocolind repository-ul.

Returnând o copie, modificările la lista primită nu afectează FakeDatabase.Carti:

Un detaliu tehnic de reținut: se copiază lista, nu obiectele din ea. Obiectele Carte din copie sunt aceleași referințe ca cele din FakeDatabase.Carti. Modificarea unei proprietăți pe un obiect primit prin GetAll() se va reflecta și în FakeDatabase. Aceasta este o limitare acceptabilă pentru exercițiu — în aplicații reale s-ar folosi obiecte imutabile sau clonare profundă.

Ce nu aparține în repository

Repository-ul nu validează date și nu afișează niciun mesaj vizual. Aceste responsabilități aparțin formularelor din stratul de prezentare.

Dacă repository-ul ar conține MessageBox.Show, nu l-am putea reutiliza niciodată într-o aplicație consolă sau web. Menținând repository-ul pur — doar operații pe date — el devine utilizabil în orice context.

Last updated