Das Repository-Pattern und der O/R-Mapper: Geniale Kombination oder vergebene Liebesmüh?

Preview:

DESCRIPTION

Wenn Sie sich Beispielcode im MSDN ansehen, dann wird Eines ganz schnell klar: Wer einen O/R-Mapper wie das Entity Framework oder NHibernate einsetzt, der sollte ihn mit dem Repository Pattern paaren. Idealerweise sogar mit generischen Repositories. Schließlich können Sie nur so den O/R-Mapper Ihrer Wahl vor den darüber liegenden Schichten verbergen. Aber ist dieses Versteckspiel vorteilhaft? Wie sinnvoll ist es wirklich, höhere Schichten bewusst dumm zu halten? Und gewinnen Sie auch Flexibilität durch diese Herangehensweise? Genau um diese Fragen geht es in diesem Vortrag. Anhand einiger Praxisbeispiele werden wir uns im Vergleich zu den typischen MSDN-Anwendungen ansehen, ob das Repository Pattern tatsächlich seine Berechtigung hat.

Citation preview

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

Xing

Facebook

Twitter

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

Recommended