das repository-pattern und der o/r-mapper: geniale kombination oder vergebene liebesmüh?
Post on 24-Jan-2015
903 Views
Preview:
DESCRIPTION
TRANSCRIPT
Das Repository-Pattern und der O/R-Mapper:
Geniale Kombination oder vergebene Liebesmüh?
André Krämer
Softwareentwickler, Trainer, Berater
Video Trainings ZertifizierungenAuszeichnungen
Was machen wir eigentlich den ganzen Tag?
Customer
Order OrderItem
Product
orders*
0…*
1
Name Street City Date
Customer Orders Id
OrderItem
City PriceShippe
d
Relation-ship
Relation-ship
DataReader (.NET 1.0 Style)
using (connection) { SqlCommand command = new SqlCommand( "SELECT CategoryID, CategoryName FROM Categories;", connection);
connection.Open(); SqlDataReader reader = command.ExecuteReader();
if (reader.HasRows) { while (reader.Read()) { Console.WriteLine("{0}\t{1}", reader.GetInt32(0), reader.GetString(1)); } } else { Console.WriteLine("No rows found."); } reader.Close(); }
30 % der Arbeitszeit sind verloren
• ?
?
ORMs (Entity Framework)
NHibernate
OR-Mapper
• Abbildung von Tabellen auf Klassen• Objektorientierte Sicht auf die Datenbank• Es muss kein SQL mehr geschrieben werden• Eine weitere Abstraktionsschicht
Einsatz des O/R Mappers
Beispiel entnommen aus: http://www.asp.net/mvc/tutorials/getting-started-with-ef-5-using-mvc-4
Beispiel entnommen aus: http://www.asp.net/mvc/tutorials/getting-started-with-ef-5-using-mvc-4
Beispiel entnommen aus: http://www.asp.net/mvc/tutorials/getting-started-with-ef-5-using-mvc-4
public ActionResult Index(){}
public ActionResult Details(){}public ActionResult Create(){}public ActionResult Edit(){}
public ActionResult Delete(){}
Daten-bank
EF Context & Models
Typischer Einsatz desO/R MappersIn Kombination mit dem Repository Entwurfsmuster
Entwurfsmuster
• Lösungsschablone für wiederkehrende Probleme• Keine direkte Lösung, sondern Beschreibung eines
praxiserprobten Lösungswegs
Repository Muster
Mediates between the domain and data mapping layers using a collection-like interface for accessing domain objects.
Repository Muster (2)
• Client objects construct query specifications declaratively and submit them to Repository for satisfaction
• Objects can be added to and removed from the Repository, as they can from a simple collection of objects, and the mapping code […] will carry out the appropriate operations […]
Anwendung desRepository Muster
Variante 1
Variante 2
public ActionResult Index(){}
public ActionResult Details(){}public ActionResult Create(){}public ActionResult Edit(){}
public ActionResult Delete(){}
Daten-bank
EF Context & Models
Repository
Gründe für den Einsatz
Warum Repositories?
• Austauschbarkeit der Datenzugriffsschicht durch Kapselung
• Wiederverwendbarkeit komplexer Abfragen durch Kapselung
• Testbarkeit• Haben wir immer schon so gemacht• Ziel liegt in der Entkopplung
O/R Mapper + Repository =
Wiederverwendbarkeit komplexer Abfragen durch Kapselung
• Keine Filter in der Datenbank• Keine Sortierung in der Datenbank• Kein Include oder Prefetching
Folgen der Abfragekapselung
• Umfangreiche Repository Klassen mit zu vielen Verantwortlichkeiten
• Geschäftslogik in der Datenzugriffsschicht
Wiederverwendbarkeit von Abfragen
Use Case 1
Use Case 2
Use Case 3
Use Case 4
Use Case 5
Wiederverwendbarkeit von Abfragen (2)
• Abfragen sind meist Use Case spezifisch• Änderung einer Abfrage für Use Case 1 kann Fehler in
anderen Use Cases erzeugen
Warum Repositories?
• Austauschbarkeit der Datenzugriffsschicht durch Kapselung
• Wiederverwendbarkeit komplexer Abfragen durch Kapselung• Testbarkeit• Haben wir immer schon so gemacht
Alternative Implementierung
Folgen von IQueryable als Rückgabe
• Abfragen werden nicht mehr gekapselt• Unabhängigkeit von der darunter liegenden
Datenzugriffsschicht entfällt
Was ist falsch an diesem Code?
Er läuft unter NHibernate nicht
http://stackoverflow.com/questions/14458050/sum-of-top-5-elements-in-nhibernate-linq
Warum Repositories?
• Austauschbarkeit der Datenzugriffsschicht durch Kapselung
• Wiederverwendbarkeit komplexer Abfragen durch Kapselung• Testbarkeit• Haben wir immer schon so gemacht
Testbarkeit
• Der Einsatz von Repositories ermöglicht Unit Tests der aufrufenden Klasse (Controller, Business Service)
• EF DbContext kann „gemocked“ werden
DBSetHelper Klasse
Warum Repositories?
• Austauschbarkeit der Datenzugriffsschicht durch Kapselung
• Wiederverwendbarkeit komplexer Abfragen durch Kapselung• Testbarkeit• Haben wir immer schon so gemacht
Haben wir schon immer so gemacht
• Repository Pattern entstand, bevor es O/R Mapper gab• SQL wurde per Stringverkettung erzeugt• Primär wurde mit Recordsets gearbeitet• Connection Management war komplex
• Ziel war es, diese Komplexität zu verstecken
Warum Repositories?
• Austauschbarkeit der Datenzugriffsschicht durch Kapselung
• Wiederverwendbarkeit komplexer Abfragen durch Kapselung• Testbarkeit• Haben wir immer schon so gemacht
BonusfrageWas ist problematisch an folgendem Code?
Alternativen
Einsatz von O/R Mappern im UI Code
• Manchmal!
Query Objekte
Fazit
Repositories
• Vermitteln zwischen Domain und Data-Mapping Schicht • Isoliert Domänen Objekte vom Datenzugriffscode• Verhält sich wie eine Collection• Stellt eine objektorientierte Sicht bereit
Repositories
• Vermitteln zwischen Domain und Data-Mapping Schicht • Isoliert Domänen Objekte vom Datenzugriffscode• Verhält sich wie eine Collection• Stellt eine objektorientierte Sicht bereit
O/R Mapper
Repositories
• Lösen ein Problem, das auch der O/R Mapper löst• Sind eine weitere Abstraktion, deren Pflege Kosten
verursacht• Bereiten auf die 1%ige Wahrscheinlichkeit vor, dass der
O/R Mapper getauscht werden soll
64
Homepage
andre@andrekraemer.de | http://andrekraemer.de | http://andrekraemer.de/blog
Vielen Dank!
Blog
Google+
Schulung und Beratung mit den Schwerpunkten:• Windows 8 und Windows Phone Apps• ASP.NET MVC, Web API & JavaScript• Team Foundation Server / ALM• Automatische Dokumentengenerierung mit TX Text
Control• Performance- & Memory Analysen• Softwarearchitektur
top related