Saturday, June 9, 2007

Model-View-Presenter (MVP) und seine Geschmacksrichtungen

Neulich hat Jeremy D. Miller in seinem Blog die verschiedenen Ausprägungen des Model-View-Presenter Patterns erörtert. Hier ein kurze Zusammenfassung dessen was mir wichtig erscheint:

Dem MVP liegen im allgemeinen folgende Definitionen zu Grunde:
  • Model ist eine Abbildung dessen was dargestellt wird.
  • View ist die Darstellung.
  • Presenter bringt das Model auf der View zur Darstellung und aktualisiert das Model aufgrund von Benutzereingaben.

The Autonomous View

Das 'Anti-Pattern'. Model-View-Presenter sind in einer Klasse vereint.

Supervising Controller
  • Presenter: Übergibt das Model (oder Teile davon) der View zur Darstellung. Der Presenter wird von der View aufgerufen um auf Benutzereingaben zu reagieren.
  • View: bringt das vom Presenter an die View übergebenen Model zur Darstellung (z.B mit Databinding). Leitet Benutzereingaben an den Presenter weiter.

Die View ist somit direkt vom Modell abhängig.

Passive View
  • Presenter: Kapselt das Model gegenüber der View. Übernimmt das Databinding indem die dargestellten Werte (nicht das Model) explizit der View zur Darstellung übergeben werden. Der Presenter wird von der View aufgerufen um auf Benutzereingaben zu reagieren.
  • View: Stellt die vom Presenter übermittelten Werte dar und leitet Benutzereingaben an den Presenter weiter.

Gegenüber dem Supervising Controller Pattern hängt die View hier nicht vom Modell ab.

Presentation Model
  • Presentation Model: Das Model und der Presenter sind hier zusammengeführt. Das Presentation Model zeigt gegenüber der View die darzustellenden Werte und reagiert falls ein solcher Wert verändert wird. Das Presentation Model wird von der View aufgerufen um auf Benutzereingaben zu reagieren.
  • View: Bindet das Presentation Model direkt für die Darstellung.

Für die Kommunikation zwischen View und Presenter gibt es bei allen Pattern zwei Möglichkeiten:

  1. Direkt: Die View ruft den Presenter direkt und explizit via Methoden auf (z.B im Eventhandler in der View).
  2. Indirekt: Der Presenter abonniert Events welche die View zur Verfügung stellt.

Zur Zeit verwende ich meistens das Passiv View Pattern um eine höchstmögliche Testabdeckung in den Unittests zu erreichen.

Thursday, June 7, 2007

LinqToSql vs. NHibernate

Im folgenden vergleiche ich 'LINQ to SQL' mit NHibernate und Stelle die Unterschiede und Gemeinsamkeiten dieser beiden O/R-Mapper dar.

Sessions
Was in 'LINQ to SQL' der DataContext ist in NHibernate die Session. Beide Implementationen realisieren UnitOfWork und IdentityMap was uns ein sicheres und bequemes Arbeiten mit einem DomainModel ermöglicht.


Transaktionen und Locking
Da beide O/R-Mapper UnitOfWork implementieren, unterstützen uns beide auf ähnliche Weise beim optimistischen Locking. Beide O/R-Mapper halten den für das optimistische Locking nötigen Ursprungszustand der Objekte intern, also im DataContext oder in der Session.

Für das pessimistische Locking ermöglichen beide O/R-Mapper den Zugriff auf die Transaktion auf welcher der Transaktionsbeginn und -ende, sowie der Isolationslevel gesteuert werden kann.


Persistence Ignorance (PI)
Nur NHibernate ermöglicht das Persistieren von beliebigen Objekten. Bei 'LINQ to SQL' (in Orcas Beta1) muss INotifyPropertyChanging und INotifyPropertyChanged implementiert werden. In 'LINQ to SQL' kann wahlweise die Mapping-Information auf der Klasse als Attribute oder in einem externen XML abgelegt werden.

Eliminierung O/R Impedance-Mismatch
Hier zeigt sicher der größte Unterschied zwischen den beiden O/R-Mappern. Folgende nicht abgeschlossene Liste zeigt Features welche NHibernate unterstützt, 'LINQ to SQL' aber nicht:

  1. Abfragen berücksichtigen unpersistierte Änderungen
  2. Unterstützung mehrerer Abbildungsarten für die Vererbung ( table-per-class / table-per-subclasss / table-per-concrete-class )
  3. Mapping von n-m Beziehung

Da 'LINQ to SQL' den Punkt 1. nicht unterstützt müsste zum Beispiel mit Aggregates (Eric Evans: Domain Driven Design) gearbeitet werden. Diese würden die unpersistierten Änderungen in ihrem Aggregate berücksichtigen und verwalten.

Abfragesprache
'LINQ to SQL' ist mit der Abfragesprache LINQ zur Zeit hier im Vorteil. Eine LINQ-Implementation für NHibernate ist aber in Bearbeitung und danach wird es unter diesem Punkte keine nennenswerte Unterschiede geben.


Wartung
Hier sehe ich keine grossen Unterschiede, da das Warten der Mapping-Informationen immer eine mühsame Angelegenheit ist. Mit dem 'LINQ to SQL' -Designer (Beta1) kann sehr schnell eine erste Version eines Mapping-Schemas erstellen werden. Die Wartung und Pflege des Schemas erfolgt danach aber manuell.

Falls jemand schon praktische Erfahrungen in einem grösseren Projekt mit 'LINQ to SQL' hat, würde ich mich über einen Erfahrungsbericht sehr freuen.

So nun muss ich mir noch LINQ To Entities anschauen!






Wednesday, May 30, 2007

Mein erster Blogeintrag

Heute will ich meinen ersten Blogeintrag veröffentlichen. Ein Vorsatz der ich mir schon länger vorgenommen habe!

Als analytisch, vorsichtig und strukturiert denkender Mensch musste ich mir aber zuerst einige Fragen beantworten, bevor ich nun mit meinem ersten Blogeintrag starte.

Frage: Soll ich auf Englisch oder Deutsch schreiben?
Antwort: Ich schreibe auf Deutsch da mein Deutsch besser als mein Englisch ist. Falls ich jemals so schlaue Sachen schreiben werde dass es auch die "englische Welt" wissen sollte, wechsle ich die Sprache.

Frage: Über was schreibe ich?
Antwort: Ich schreibe über Softwareentwicklung wie ich sie verstehe, was ich davon verstanden habe oder was ich noch verstehen möchte. Ich schreibe hier über Softwareentwicklung da dies mein Job und einer meiner Leidenschaften ist. Falls ich damit die Welt verändern kann, werde ich vielleicht auch mal über Sachen sprechen welche mich persönlich beschäftigen.

Frage: Warum schreibe ich?
Antwort: Da ich schon immer das Bedürfnis hatte den anderen die Welt aus meiner Sicht und Überzeugung zu erklären. Und natürlich bin ich auch gespannt ob der Blog tatsächlich auch jemals von jemanden gelesen wird.

Also los ... mal schauen was daraus wird.

Monday, May 28, 2007

p geht zu f

Mit der nächsten Version von .NET (Codename 'Orcas') werden wir tagtäglich mit Lambda-Ausdrücken arbeiten. Doch wie spricht man ein Lambda-Ausdruck überhaupt aus?

Was ist zum Beispiel mit p => f => f(p) ?

Wes Dyer vom C# Compiler Team spricht es in einem Interview als 'goes to' aus. In Englisch ist das also p goes to f goes to f(p). Ich finde dies in Ordnung aber beim Einsetzen der Variable f im Ausdruck f => f(p) finde ich das 'goes to' ungenau, da neben dem Binden der Variable f auch gleich die Funktionsapplikation f(p) stattfindet.

Eric White spricht in seinem Blogeintrag, abhängig von jeweiligen Kontext, von einem 'becomes' oder 'such that'.

Für das oben genannte Beispiel finde ich p goes to f becomes f(p) das Beste, weil der Lambda-Ausdruck in folgenden Schritten evaluiert wird:
  1. 'p => f' oder 'p goes to f', da nach dem Einsetzen der Variable p eine anonyme Methode resultiert welche p bindet und f als Parameter hat. In dem Sinne geht also p zu f, oder eben 'p goes to f'.
  2. 'f => f(p)' oder 'f becomes f(p)', da nach dem Einsetzen von f die Funktion f(p) ausgeführt wird. In dem Sinne wird als f in f(p) umgewandelt, was auf Englisch dann auch als 'f becomes f(p)' ausgesprochen werden kann.

Ich werde also in Zukunft das letzte '=>' als 'becomes' und alle vorangehenden '=>' als 'goes to' aussprechen.

Beispiele:

  • 'a => b => a+b' ist 'a goes to b and becomes a+b'
  • 'a => 1 + a' ist 'a becomes 1+a'