20. juli 2011 - 16:30Der er
11 kommentarer og 2 løsninger
Type libraries ved brug af repository pattern
Hej
Jeg har lige et begynderspørgsmål. Jeg er i gang med at kigge på oprettelsen af et DAL ved brug af repository pattern (se evt. dette andet spm jeg har stillet).
I forbindelse med dette er jeg i gang med at lave de type libraries der skal bruges til at mappe dataene fra databasen. Jeg har en lang række data jeg henter om en sag (det er en sagsbehandlingapplikation jeg arbejder på), f.eks. id, navn, starttid,sluttid, ejer, pris og mange andre data.
Nogle steder i applikationen skal jeg kun bruge en del af disse data og andre steder alt data. Vil det så være bedst at lave flere type libraries? Et til hver situation f.eks?
Jeg har selv ofte spekuleret på hvad der er rigtig at gøre i denne situation og har i den forbindelse overvejet, om det ville give mening at oprette en klasse (eller et hierarki som omhandler det samme - builder pattern?), hvor man så kunne angive om alt skulle indlæses eller kun en del af objektets struktur, f.eks. via nogle settings på objektet eller som parametre til læserutinen. De indeholdte lister og underobjekter kunne så implementeres via lazy-loading, dvs. load on demand, hvis de ikke er indlæst i forbindelse med sagens læserutine...
Om dette så rent faktisk er det du efterspørger er jeg lidt usikker på, men det er da et bud :-)
Hvis du bruger et ORM og splitter data op i forskellige klasser med ref fra main data klasse til andre data klasser, saa boer du faa lazy loading gratis.
Men spoergsmaalet er om der er en pointe.
Hvis data er gemt i samme raekke i databasen og hvis det er forholdsvis smaa data (faa hundrede bytes), saa tror jeg ikke at lazy loading sparer noget overhovedet.
Jeg ville umiddelbart lave nogle specifikke funktioner i repositoryklassen, som hente de data der var behov for, men jeg kan ikke helt gennemskue om dette forbryder sig mod tanken med repository pattern.
Dette ville jeg vælge med henblik på at få den bedste performance, fordi jeg givetvis kan generere nogle meget specifikke joins af data i repository-klassen, som løser den konkrete opgave...
Lige i første omgang bruger jeg ikke et færdigbygget ORM, men laver bare mine egen database tilgang. Kan ikke helt beslutte mig, hvad jeg skal bruge MS EF, Subsonic, NHibernate osv.
Lige præcis i det her tilfælde vil lazy loading nok være overkill, da det er forholdsvis lidt data jeg skal læse, men på sigt er det da godt at vide, at der er sådan det skal/kan gøres.
@softspot - jeg har lidt haft det samme spm ifht joins. Er lidt i tvivl om man i sin repository class bare henter de givne data der så bliver proppet ind i type libraries, og så håndterer man joining af data bagefter, eller om man klarer det direkte i em query til databasen.
"Min" strategi er med stor sandsynlighed ikke optimal ifht. vedligeholdelsen af koden, da den umiddelbart vil medføre dublering af visse kodepassager (så den forbryder sig på DRY-princippet), men hvis man skal arbejde med store datamængder eller mange entiteter, kan jeg ikke lige komme i tanke om andre måder som performer ordentlig når det skaleres.
Ret beset bryder det jo ikke det interface man har til sit repository, men på den anden side så bliver interfacet til repository mere komplekst på denne måde.
Er det et typisk problem at skulle finde ud af, hvordan man inddeler i, hvad der udføres i database udtrækket, og hvad der laves i business laget? Eller er der en "optimal" løsning, eller er det et spørgsmål om, hvad man hælder til?
Til det jeg laver har jeg mest brug for at det er vedligeholdelsesvenligt og så er performance 2. prioritet. Jeg forudser, at der ikke kommer så stort en datamængde, men at der kommer til at være andre der skal rette i det jeg laver.
arne >> Jeg er stadig lidt usikker på om du mener det er OK at sende filtreringen ned i datalaget, eller om du vil holde datalaget helt "rent" (CRUD) og så lægge filtreringen i BLL?
Fordelen ved at lægge filtreringen i BLL er vel, at man lettere kan skifte DAL, da det blot bliver en simpel kobling mellem databasen og forretningsobjektet (men det er vel det ORM er til for?).
Ulempen er så hvis der skal samles data fra en række forskellige tabeller, for så ville man vel skulle forbinde til databasen mange gange for at få de nødvendige data overført til objekterne... eller er der en smart metode til at undgå dette?
PÅ den anden side er det at filtreringen ligger tættere på opslaget i databasen en fordel for performance, men når dette lag så skal udskiftes, får man en mere kompleks opgave, da der så ligger en del flere beslutninger i DAL.
I den første løsningsmodel, kan man sikkert klare sig et stykke hen ad vejen med caching (i DAL), men jeg vil mene den har en begrænsning når systemet skalerer... hvad er dit syn på dette?
Hvad betyder filtrering i DAL? Hvis det er filtrering imod allerede cachede entiteter, så synes jeg det er en dårlig idé :) Så er det langt bedre at filtrere hvor du skal bruge dataen eks.vis i BLL.
Hvis du derimod vil opbygge din sql dynamisk udfra filtreret så vil du få svært ved at cache det medmindre det er nogle simple cachekeys.
Jeg syntes du måske opfinder et problem for at løse "hvis nu db'en udskiftes" og samtidigt erstatter den af et andet :) Nemlig det hvis nu datamodellen ændres en smule skal du eller andre på overarbejde, sandsynligheden for at datamodellen ændres er ofte langt større end for at dbms udskiftes.
Du spørger også lidt til flere typelibs, jeg vil altid begrænse typelibs så meget som muligt, der findes ikke noget mere irriterende end at sidde og skulle arbejde med adskillige typelibs for noget banalt indenfor samme domæne.
Hvis vi nu ser bort fra ORM, så..... Hvis du ikke har så meget data, så opbyg en objektgraf for hver sub dataområde og populer med alt data fra området, dvs. lav dine joins i DAL og byg parent-childs op. Udstil objektgraferne fra dit DAL og tilgå objektgraferne igennem namespaces og metodekald, brug objektgraferne i dit BLL :)
Lad være med at tro at BLL-koderne kender til dine datarelationer, klar disse i DAL vha. joins eller endnu bedre igennem views ;-) Pas på ikke at introducere flere problemområder ved at skifte DBMS end ved blot at benytte dig af de tilgængelige metoder for datatilgang, det bliver sku hurtigt alt for teoretisk, unødigt kompliceret og tilmed "ligegyldigt", hvis du forstår :)
Datatilgang er triviel er skal holdes sådan, KISS :)
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.