Follow my new blog

Dienstag, 25. September 2007

Gesetze der Softwareentwicklung I

Ja, ja, ich weiß, bei der Softwareentwicklung ist immer alles immer wieder anders. "Es kommt darauf an!" ist die Antwort auf fast jede Frage nach Einsatz einer Technologie oder eines Konzeptes. Grundsätzlich stimmt das natürlich auch. Meistens. Oft. Wie auch sonst so im Leben.

Aber es lässt sich nicht leugnen, dass wir uns alle nach Gewissheiten und Regeln sehnen. Irgendwo muss es doch mal feste Standpunkte geben, oder? Absolute Ansatzpunkte für Hebel, mit denen wir die Welt aus den Angeln heben können.

Und tatsächlich, die gibt es. Bei mehreren Beratungsterminen in der letzten Zeit sind sie mir klar geworden. Heute während eines online Unterrichts zur Einführung in den .NET Framework (ja, damit experimentiere ich; wer Interesse an einem solchen ".NET Basics Personal Training" hat, melde sich gern bei mir per Email) ist mir dann noch ein weiterer "Baustein" eingefallen, der mich nun auch veranlasst, mal darüber zu schreiben.

Also bin ich mal so kühn und behaupte, dies seien fünf grundlegende Gesetze der Softwareentwicklung:

  1. Strukturen können immer nur optimal für bekannte Anforderungen sein.
  2. Optimale Strukturen lassen sich nicht aus Anforderungen ableiten.
  3. Optimale Strukturen werden nie verlustfrei implementiert.
  4. Strukturen, die für bekannte Anforderungen aus schon existierenden weiterentwickelt werden, sind nie optimal in Bezug auf die gesamte Anforderungsmenge.
  5. Anforderungen werden durch implementierte Strukturen beeinflusst.

Der Begriff "Struktur" steht in den Gesetzen sowohl für die grobe wie die feine Organisation. Er bezieht sich also sowohl auf Auswahl und Anordnung von Anweisungen, Methoden, Klassen, Komponenten, Prozessen, Dienste usw. Gemeint sind auch nicht nur Bausteine auf unterschiedlichen Abstraktionsebenen, sondern ebenfalls ihre Anordnung, d.h. wie sie in Beziehung zueinander gesetzt sind.

"Optimale Strukturen" sind dann Strukturen, die nicht nur die funktionalen und nicht-funktionalen Anforderungen erfüllen, sondern auch etwas Luft lassen für neue Anforderungen bzw. unvermeidliche Fehlerbehebungen. Optimale Strukturen sind verständlich und wartungsfreundlich, flexibel und testbar. Bei ihrem Anblick sollen Sie ausrufen "Toll! Einleuchtend! Ideal!". Optimale Strukturen haben insofern auch immer etwas von einem Kunstwerk. Sie sollen auch "schön" sein. Aber nur "auch", denn ihr Hauptzweck ist ja die Erfüllung von knallharten Anforderungen.

Aber ich möchte mich auch nicht an der Optimalität festklammern. Statt "optimal" können Sie auch "gut" oder "sehr gut" oder ein noch weniger wertendes "angemessen" lesen.

Was bedeuten nun aber suboptimale Strukturen? Ist es schlimm, wenn eine Software nur eine suboptimale Struktur hat? Suboptimal bedeutet ja nicht, dass die Software nicht funktioniert. Sie erfüllt die "platten", gut greifbaren funktionalen und nicht-funktionalen Anforderungen des Kunden. Aber: Suboptimale Strukturen machen es schwerer als nötig, Änderungen einzuarbeiten. Seien es Fehlerbehebungen, Änderungen an Features oder ganz neue Features. Änderungsfreundlichkeit aber ist - so finde ich - ein hohes Gut - auf das viele Projekte leider de facto zuwenig Wert legen. Direkt nach dem Wert von Änderungsfreundlichkeit gefragt, finden Projektteams sie zwar womöglich wichtig. Aber wenn man dann in den Code schaut, spiegelt sich diese Wertschätzung nicht wider. Sie ist - sorry to say - oft ein Lippenbekenntnis, dass man - soviel zur Entlastung der Softwareentwickler - gern in die Tat umsetzen würde, aber nicht zu können glaubt, weil "eine höhere Macht" (Kunde, Chef) das nicht zulässt.

Insofern mögen die folgenden "Gesetzeserklärungen" oder "Erklärungen der Gesetze" auch helfen, "höhere Mächte" eine andere Sicht auf Software zu vermitteln.

Gesetz 1: Optimale Strukturen für bekannte Anforderungen

Dass optimale Strukturen nur für bekannte Anforderungen ermittelt werden können, ist eigentlich kaum der Erwähnung wert. Interessant ist hingegen der Umkehrschluss: Zu unvollständigen oder schwammigen Anforderungen lassen sich keine optimalen Strukturen finden. Das bedeutet nämlich für die Softwareentwicklung, deren Projekte notorisch unterspezifiziert sind, dass ihre Strukturen quasi notwendig immer suboptimal sind.

Das Wasserfall-Vorgehensmodell hat versucht, sich dagegen zu stemmen. Es basierte auf der Annahme, Anforderungen ließen sich vollständig ermitteln. Wie die Agilitätsbewegung inzwischen ja aber hinlänglich klar gemacht haben sollte, ist das allermeistens eine Illusion. Sie können die Anforderungen an eine Software nie vollständig erheben. Anforderungen sind ständig in einem mehr oder weniger schnellen Fluss. Jedes Release Ihrer Software implementiert also nur eine vorläufige Menge von Anforderungen, einen Schnappschuss.

Dazu kommt noch, dass Projekte so groß sein können, dass die schiere Menge der Anforderungen Sie zwingt, sie in mehreren Schritten zu implementieren, die jeweils nur eine Untermenge abdecken. Selbst also bei grundsätzlich bekannten Anforderungen können Sie nicht immer all diese Anforderungen auch zur Strukturierung heranziehen. Es würde schlicht zu lange dauern, bis der Kunde ein erstes Ergebnis erhält.

Das bedeutet: Da zu einem bestimmten Zeitpunkt entweder nicht alle Anforderungen bekannt sind oder nur eine Untermenge von Anforderungen berücksichtigt werden kann, hat Software immer eine suboptimale Struktur auf das "große Ganze" bezogen:

  • Wenn nicht alle Anforderungen bekannt sind, dann muss die Implementierung der bekannten Anforderungen suboptimal in Bezug auf die erst später bekannte gesamte Anforderungsmenge sein. Das gilt auch, wenn die Struktur für die implementierten Anforderungen optimal ist! Siehe dazu auch Gesetz 4.
  • Wenn Sie nur eine Untermenge bekannter Anforderungen implementieren, dann mag die Struktur in Bezug auf die Untermenge optimal sein - aber nicht gleichzeitig für alle Anforderungen.

Ohne weiteren Aufwand hat Software also immer eine suboptimale Struktur. Sie ist damit weniger als möglich und nötig änderungsfreundlich. Und das wird nicht besser, wenn Sie weitere Anforderungen implementieren. Zumindest nicht, wenn Sie nicht explizit etwas dagegen tun.

Gesetz 1 beschreibt etwas Unvermeidliches: Suboptimalität. Die Qualität von Software ist immer geringer als sie sein könnte, weil wir nie alle Anforderungen im Blick haben können. Wer Software entwickelt, sollte sich also vom Gedanken der Perfektion verabschieden. Die mag sich vielleicht noch für einen Sortieralgorithmus erreichen, aber nicht mehr für eine ganze Anwendung.

Allerdings ist Gesetz 1 keine Entschuldigung für schlechte Qualität! Es macht nur klar, das wir uns nach hoher Qualität immer strecken müssen. Es gibt dabei kein Ankommen. Zwischen dem, was ist, und dem, was am besten wäre, ist immer eine Lücke. Hoffentlich wird die immer kleiner im Verlauf eines Projektes, doch schließen können Sie sie nicht.

Insgesamt hohe Qualität oder vor allem Änderungsfreundlichkeit als Grundlage für ein langes Softwareleben ergibt sich damit nicht einfach so, sondern erfordert bewussten Energieeinsatz. Akzeptieren Sie Suboptimalität, aber stemmen Sie sich gleichzeitig dagegen.

Mehr dazu im nächsten Posting.

Freitag, 6. Juli 2007

Mein aktuelles Steckenpferd: Software Transactional Memory

Früher hatte Vati die elektrische Eisenbahn als Steckenpferd. Und heute? Heute hat Vati einen Windows Media Edition PC, der ihn nicht mehr zur Ruhe kommen lässt ;-) Nur ich tanze da wohl aus der Reihe. Aber ich habe ja auch kein Auto. Die Media Edition interessiert mich nicht, dafür aber Software Transactional Memory (STM). Das (!) ist cool. Viel cooler als an einem PC rumzuschrauben :-)

Und was soll so ein STM? Der macht z.B. die Programmierung mit mehreren Threads einfacher. Statt den Zugriff auf gemeinsame in-memory Ressourcen durch ausgeklügelte Sperren zu synchronisieren, arbeiten Sie einfach mit Transactionen. Genau: Transactionen wie bei Datenbanken - nur eben nicht auf persistenten Daten, sondern im Hauptspeicher!

Wem das aber noch nicht cool genug erscheint, der kann damit auch ohne Multithreading Undo-Lösungen basteln. Und das nicht nur auf einer Ebene, sondern auch echt geschachtelt. Das kann nicht mal SQL Server :-)

Und wer das noch nicht cool findet, der kann auch verteilte Transaktionen fahren: Mit System.Transactions eine Transaction öffnen, auf SQL Server zugreifen und Veränderungen im STM vornehmen - und am Ende alles zusammen committen oder zurückrollen.

Hier das kanonische Beispiel für Transaktionen mit dem .NET Software Transactional Memory (NSTM) realisiert: Überweisung eines Betrags von einem Konto auf ein anderes.

    1 INstmObject<double> myAccount;

    2 INstmObject<double> yourAccount;

    3 

    4 myAccount = NstmMemory.CreateObject<double>(1000);

    5 yourAccount = NstmMemory.CreateObject<double>(500);

    6 

    7 using (INstmTransaction tx = NstmMemory.BeginTransaction())

    8 {

    9     double amountToTransfer = 150;

   10 

   11     myAccount.Write(myAccount.Read() - amountToTransfer);

   12     yourAccount.Write(yourAccount.Read() + amountToTransfer);

   13 

   14     tx.Commit();

   15 }

   16 

   17 Console.WriteLine("My account balance: {0}", myAccount.Read());

   18 Console.WriteLine("Your account balance: {0}", yourAccount.Read());

In Zeile 16 hat der Transfer entweder komplett geklappt oder gar nicht. Inkonsistenzen, die durch einen Fehler in der Verarbeitung (Zeilen 9 bis 12) auftreten könnten, haben keine Chance, nach außen "durchzulecken". Wie gesagt: das ist wie mit Transaktionen bei Datenbanken. Wer sich den Code genau ansieht, wird das feststellen und auch sehen, dass er sehr dicht an Code ist, den man mit "normalen" Variablen geschrieben hätte.

NSTM ist mein Versuch der Implementation von STM, nachdem ich von dem Konzept neulich gehört hatte. Da war ich fasziniert und hab ne Menge drüber gelesen. Aber dann musste ich es einfach ausprobieren. Allemal, da die verfügbaren Implementationen alle irgendwie hinken. Entweder in Java realisiert oder unter Zuhilfenahme von Unmanaged Code oder nur für Haskell oder irgendwie nicht dem "normalen" Programmiermodell entsprechend, das wir von Transaktionen kennen. Also hab ich das gemacht, was alle Entwickler gern tun: ich habe meine eigene Infrastruktur gebastelt. Und es hat Spaß gemacht :-)  Aber dafür ist ein Steckenpferd ja auch da.

Wer mehr über NSTM erfahren will, kann in meinem englischen Blog eine ausführliche Darstellung lesen. Das Thema hab ich für international interessant gehalten und deshalb dort zuerst darüber geschrieben. Man sehe es mir in der deutschen Community nach.

Samstag, 19. Mai 2007

WCF Literaturhinweise

Der ganze Indigo-Hype ist an mir früher genauso vorbeigegangen wie es heute der Orcas-Hype tut. Ich habe einfach keine Zeit, mich mit Technologien zu beschäftigen, die so wenig real sind und noch so unbestimmt weit in der Zukunft liegen. Vielen von Ihnen wird es nicht anders gehen.

Jetzt aber ist Indigo real und heißt Windows Communication Foundation (WCF) und ist echt cool geworden. Und jetzt lohnt es sich auch, sich damit näher auseinanderzusetzen. Auch ich habe mich deshalb auf den Weg durch das WCF-Labyrinth gemacht. Wie bei Jules Vernes "Reise zum Mittelpunkt der Erde" stellt sich dabei allerdings die Frage: Wo einsteigen in die unterirdischen Gänge? Was ist der Snaeffellsjökull für die Reise durch WCF? Welche Gänge sind anschließend zielführend? Was gibt es überhaupt zu entdecken? WCF ist ja so groß, so groß.

Nachfolgend finden Sie quasi meine Expeditionsaufzeichnungen, d.h. die Literaturstationen, die ich auf meiner Reise durch WCF als hilfreich empfunden habe. Vielleicht helfen sie Ihnen ja auch beim Einstieg in das Thema. Google macht am Ende zwar recht glücklich bei der Wegfindung - aber braucht viel Zeit. Ich würde mich also freuen, wenn Ihnen diese Quellenliste Zeit sparte.

Aber Achtung: Meine kleine Landkarte für WCF erhebt keinen Anspruch auf Vollständigkeit. Sie ist subjektiv, d.h. geprägt von meinen persönlichen Interessensgebieten in Bezug auf WCF. So bekümmere ich mich z.B. nicht um Aspekte der plattformübergreifenden Kommunikation. Aber auch zu meinen Interessengebieten sind natürlich nicht alle Quellen zu finden, weil es erstens eine unüberschaubare Vielzahl gibt und zweitens nicht alle lesenswert sind.

Wenn Sie nun mit diesen Einschränkungen leben können oder - positiver ausgedrückt - meinen Fokus teilen, dann wünsche ich viel Spaß beim Lesen:

WCF Ressourcen

WCF Einführungen und Überblicke

Bücher

  • Juval Löwy, Programming WCF Services, O'Reilly 2007
    Scheint mir derzeit die umfassendste Darstellung von WCF zu sein. Sehr detailreiche Darstellung, für einen ersten Einstieg im Grunde zuviel. In jedem Fall aber ein must-have als Nachschlagewerk. Gut gefallen hat mir der Versuch am Ende des Buches, "WCF Coding Standards" aufzustellen, d.h. knackige Dos and Donts zu formulieren.
    Die Kehrseite der Medaille ist, Juvals Darstellung ist zu einem großen Teil feature fucking. WCF wird weitestgehend ohne Anwendungszusammenhang dargestellt; der Leser wird mit dem Transfer in die Praxis, d.h. mit dem Abwägen der vielfältigen Optionen alleingelassen. Auch kann man geteilter Meinung darüber sein, ob Juval das Thema konzeptionell optimal angeht. Seine Beschreibungen lassen eine, hm, gewisse Verhaftung mit der guten alten COM+/Enterprise Services Welt vermuten. Die Andersartigkeit echt nachrichtenorientierter Kommunikation im Gegensatz zum RPC-orientierten Umgang mit verteilten Objekten wird nicht wirklich thematisiert.
    Insofern ist Juvals Buch vielleicht nicht das beste, aber zumindest derzeit das kleinste Übel. Ich habe es jedenfalls gern gelesen.
  • Ralf Westphal, Christian Weyer, .NET 3.0 kompakt, Spektrum Akademischer Verlag 2007
    Mein eigenes Buch, das ich zusammen mit Christian geschrieben habe, empfehle ich nicht, weil es eben unser Buch ist, sondern weil es mir wirklich beim Einstieg in WCF geholfen hat. Ich hatte für meine ersten Gehversuche nach Beispielen gesucht, die kleinschrittig sind - und sie bei Christian gefunden. Darüber hinaus bietet das Buch aber natürlich noch mehr... ;-)

Andere Darstellungen in Buchform zu WCF habe ich auch durchgesehen (z.B. von MSPress, Apress, Wrox), war aber nicht überzeugt. Den Detaillierungsgrad von Juvals Buch erreichen sie nicht. Und sie gefallen mit vom Layout her auch nicht genauso gut wie Juvals. Oft ist die Schrift groß und die Informationsmenge pro Seite klein. Das macht auf mich dann den Eindruck, der Verlag hätte vor allem ein dickes Buch im Auge gehabt, um einen hohen Preis verlangen zu können, und nicht unbedingt ein inhaltsreiches.

Artikel

WCF Details

BizTalk Connectivity Services [home]

Themen im WCF Umfeld

Mittwoch, 18. April 2007

Auswahlhilfe beim persistence.day

Gestern hat die dotnetpro wieder den persistence.day (p.day) veranstaltet. Im letzten Jahr gab es ihn wegen der großen Nachfrage zweimal, in diesem Jahr zunächst einmal - diesmal in München. 140 Teilnehmer wollten sich einen Tag lang gezielt zum Thema Persistenztechnologien informieren. Der p.day bot dafür eine sehr schöne Möglichkeit, denn wohl auf keiner sonstigen Konferenz trifft man so geballt, Hersteller-Know-How an. Da ging es nicht um Marketing-Blabla, sondern es ging ans Eingemachte. Die O/R Mapper Genome, NDO, Persistor.Net und OpenAccess waren mit ihren Entwicklern vertreten wie auch die Hersteller der Datenbanken db4o und TurboDb. Insbesondere über Carl Rosenberger - Erfinder und Chefarchitekt von db4o - habe ich mich gefreut; ihn konnte ich noch wenige Wochen vor dem Event motivieren, einen Vortrag zu halten.

Und ich hatte die "ehrenvolle Aufgabe", den Event mit einer General Session zu eröffnen. Zuerst wollte ich darin typische Vertreter der Persistenztechnologieklassen vorstellen und den Unterschied der Programmiermodelle herausarbeiten. Dann aber... kam mir in der letzten Woche bei der wie immer gerade noch rechtzeitigen ;-) Vorbereitung des Vortrags eine viel bessere Idee: Warum nicht den Teilnehmern sozusagen eine Karte für den Persistenztechnologiedschungel geben? Ist es nicht das, was ein Event wie der p.day leisten soll? Konkrete Guidance und Strukturierungshilfe für ein komplexes Thema? Genau!

Deshalb habe ich - etwas ad hoc, aber immerhin - einen Frage- bzw. Selbsteinschätzungbogen entwickelt und vorgestellt. Der wurde durch die dotnetpro allen Teilnehmern mit ihrer Konferenztasche ausgehändigt. Mit ihm konnten sie angeleitet durch meine Erläuterungen im Vortrag ihren Anforderungen an eine Persistenztechnologie reflektieren und priorisieren - und dann die Aussteller ins Kreuzverhör nehmen. Teilnehmer wie auch Aussteller haben gesagt, das sei eine echte Hilfe gewesen.

"Danke für die vielen Denkanstöße.
Und danke für die Liste. Die ist sehr wertvoll!"

Tibor Odehnal, Teilnehmer am persistence.day

Das freut mich. (Noch besser wäre die Hilfe natürlich gewesen, wenn sie den Ausstellern vorher bekannt gewesen wäre. Dann hätten sie sich dazu schon Gedanken machen können. Naja... nächstes Mal  ;-)

Da nun mein Vortrag keinen Code gezeigt hat und recht untechnisch war, biete ich hier einen kleinen Trost:  Das Kapitel zum Thema LINQ aus dem Buch ".NET 3.0 kompakt", das ich zusammen mit Christian Weyer geschrieben habe.

Wer also Interesse an LINQ hat oder mal in unserem neuesten Büchlein probelesen will , der klicke hier.

Viel Spaß beim Lesen!

 

 

 

 

 

PS: So entspannt und zufrieden sahen übrigens einige Aussteller auf dem p.day aus :

v.l.nr.: Joachim Dürr von iAnywhere, dem Hersteller des Advantage Database Servers, Peter Pohmann von dataweb, dem Hersteller von TurboDb, und Peter Brunner von Vanatec, dem Hersteller des O/R Mappers OpenAccess

Sonntag, 25. März 2007

Contract-first Design Beispielcode und Tool-Hinweise zu User Group Vorträgen

Am 20.3. und 22.3. habe ich Vorträge zum Thema Contract-first Design vor den .NET User Groups in Ulm und München (Download des Beispielcodes) gehalten. Insgesamt lauschten knapp 80 Entwickler meinen Vorschlägen, wie Software ganz grundsätzlich mit Komponenten als binären Codebausteinen diesseits von SOA-Services und jenseits von Objekten strukturiert werden sollte.

Mit Komponenten habe ich da natürlich das gemeint, was ich in meiner Serie "Software als System" als hybrides Swolon im Schnittpunkt zwischen logischer und physischer Swolon-Hierarchie bezeichne. Auf den Weg von den Anforderungen zu den Komponenten oder das Big Picture von "Software als System" konnte ich allerdings nicht eingehen. Dafür war die Zeit zu knapp. Schon die theoretische Begründung und praktische Demonstration echter Komponentenorientierung hat ja 2-3 Stunden gebraucht - und alle UG Mitglieder haben tapfer ausgehalten.

Und hinterher gab es auch noch interessierte Diskussionen, auch wenn die Implikationen meiner Vorschläge einige recht still gemacht hatten. Echte Komponentenorientierung bedeutet nicht nur, Klassen mal wieder mit Interfaces zu versehen, sondern funktioniert nur auf der Basis eines veränderten Entwicklungsprozesses und einer klareren Codeorganisation, als in den meisten heutigen Projekten. Ich hoffe aber, ich konnte auch den Nutzen eines Umdenkens in Richtung echter Komponentenorientierung vermitteln. Wer mehr Produktivität, bessere Testbarkeit, mehr nutzbringende Dokumentation oder schlicht mehr Qualität und Seelenfrieden haben möchte... der kommt um einige Kurskorrekturen in der Softwareentwicklung leider nicht herum.

Zum Glück machen ein paar Tools den Einstieg aber leichter. Konsequente Komponententests brauchen zwar vor allem guten Willen, wenn der dann aber da ist, sind sie technisch recht einfach. VSTS enthält z.B. einen Unit Test Framework, der auch mit TFS integriert ist. Wer das Geld für VSTS allerdings nicht hat, muss nicht zurückstehen. NUnit ist die Mutter aller automatischen Tests und kostenlos. Allerdings ist NUnit nicht wirklich gut in VS2005 integriert. Macht aber nichts, denn NUnit-kompatible Werkzeuge wie Testrunner (s. folgende Abbildung) oder TestDriven lösen das Problem fast oder ganz kostenlos.


Klicken für Originalbild

Ich bin mit Testrunner schon länger sehr zufrieden. Der macht Unit Tests während der Entwicklung wirklich schmerzfrei und bietet darüber hinaus auch noch eine Codecoverage-Analyse und Profilinginformationen.

Aber Tests während der Entwicklung sind natürlich nicht alles. Echte Komponentenorientierung zerlegt eine Lösung in viele Assemblies, die in separaten VS2005 Projektmappen entwickelt werden. Die muss man den Überblick behalten und immer wieder integrieren. Ein erster natürlicher Integrationspunkt ist ein zentraler Build-Prozess, der die Komponenten periodisch unabhängig vom einzelnen Entwickler auf einem dedizierten Rechner nochmal übersetzt und testet und erst bei Fehlerfreiheit für andere zur Nutzung freigibt.

Dafür setze ich FinalBuilder ein (s. folgende Abbildung; bezieht sich allerdings nicht auf das Beispiel aus dem UG Vortrag). Ein wirklich cooles Tool, mit dem sich die Übersetzung von VS2005 Solutions, deren Test, das Deployment auf einen FTP-Server, der Umgang mit einer Versionsverwaltung uvm. automatisieren lässt. Seit ich FinalBuilder habe, schreibe ich keine Batch-Dateien mehr.


Klicken für Originalbild

Das Bild zeigt ein komponentenorientiertes Projekt aus einer Artikelserie in der dotnetpro. Rechts ist das Script zu sehen, mit dem ich alle zugehörigen VS2005 Projektmappen übersetze und teste, rechts liegt die lange Liste mit vorgefertigten Aktivitäten, aus denen ich solche Scripte zusammensetzen kann. Da bleibt kaum ein Wunsch unerfüllt. Interaktion mit virtuellen Maschinen, parallele Abarbeitung, Workflow, VSS-, SVN-, CVS-, TFS-Nutzung... alles drin.

Aber nicht nur ein umfassender Build-Prozess muss aufgesetzt werden, wenn echte Komponentenorientierung die beliebte allumfassende VS2005 Projektmappe in viele kleine zerschlägt. Es sind dann auch Integrationstestläufe womöglich außerhalb VS2005 nötig. Und der Debugger ist dann vielleicht auch nicht auf einem Staging-System zur Hand. Wer dann wissen will, was so läuft in seinem Programm, der braucht Einblick. Den kann Instrumentierung bieten (z.B. TraceSource einsetzen oder Performance Counter einrichten oder in ein Windows Log schreiben), aber ich finde es auch sehr nützlich, ohne vorgedachte Instrumentierung den Verlauf einer Software beobachten zu können. Derzeit gefällt mir dafür sehr gut SpeedTrace Pro (s. folgende Abbildung).


Klicken für Originalbild

Damit kann ich mich an ein Programm anhängen und mir den Verlauf der Arbeit protokollieren lassen. Das Ergebnis lässt sich filtern, zum Quellcode in Bezug setzen, ich kann sogar das Tracing erst bei einem bestimmten "Event" (Methodenaufruf) starten lassen.

Zuguterletzt gehört zur echten Komponentenorientierung dann noch ein Service Locator oder Microkernel. Mein eigener kleiner Microkernel steht zur freien Benutzung mit kurzen Erläuterungen online. Alternativen sind z.B. Spring.Net oder Windsor des Castle Projects. Die bieten mehr Leistung - für meinen persönlichen Geschmack allerdings oft zuviel. Ich persönlich kann mich auch nicht so recht mit dem Konzept der Inversion of Control (IoC) anfreunden, wenn es um das "Zusammennähen" von größeren Komponentengeflechten geht. Wenn es um Komponenten geht, die ich verkaufen will, oder die in Zusammenhängen eingesetzt werden sollen, in denen nicht sicher ein Microkernel vorhanden ist, dann ist IoC eine gute Sache, um Entkopplung aufrecht zu erhalten. Aber ansonsten ziehe ich innerhalb geschlossener Projekte einen Microkernel als generische Factory vor.

Ich würde mich freuen, wenn ich mit dem Beispielcode des Vortrags vor der UG München und der kleinen Werkzeugliste hier den Einstieg in die echt komponentenorientierte Softwareentwicklung ein etwas erleichtern könnte. Wer das Szenario der Beispielanwendung noch nicht kennt, der sei hier kurz eingeführt (s. folgende Abbildung):

Zwei kooperierende Komponenten sollen entwickelt werden. Die Calculator-Komponente kann Zahlenreihen zwischen zwei Grenzwerten berechnen und solche Zahlenreihen laden/speichern. Sie ist die zentrale Logik-Komponente des Szenarios und verkörpert nach außen die gesamte Funktionalität. Für die konkrete Speicherung ist dann allerdings die DataAccess-Komponente zuständig.

Beide Komponenten sind durch einen Kontrakt definiert. Die Spezifikation der Calculator-Komponente besteht aus dem Calculator- und dem DataAccess-Kontrakt, ersteren exportiert sie, letzteren importiert sie. Die Spezifikation der DataAccess-Komponente besteht aus dem DataAccess-Kontrakt, den sie exportiert, und der Beschreibung des Persistenzformats.


Klicken für Originalbild

Das ist natürlich ein supersimples Beispielszenario. Aber es ging bei der Demonstration nicht darum, komplizierte Funktionen zu implementieren, sondern den Prozess der Entwicklung echter Komponenten erlebbar zu machen. Theoretische Erklärungen am Flipchart sind eine Sache. Dann aber zu sehen, wie die Theorie in die Praxis umgesetzt wird, den Schritten wirklich zu folgen, das ist noch eine ganz andere Sache - und ein Vortrag das beste Medium, um das zu vermitteln. Ich hoffe, das hat geklappt. Freue mich über Feedback an: info (at) ralfw.de.

Freitag, 23. März 2007

Maffay neben Westphal - Kaffeehauskonsultation in Ulm

So kann es kommen: Ahnungslos fahre ich nach Ulm zur Kaffeehauskonsultation - und finde neben mir Peter Maffay. Aber nur in der Zeitung :-) Oder anders: Allerdings in der Zeitung, denn bisher hatte ich nicht geahnt, dass kostenloses .NET Technologiecoaching für die Lokalpresse von Interesse wäre. So stand es jedoch am 20.3. in der Neuulmer Zeitung:

Verständlich wurde diese Nähe zu Peter Maffay dann jedoch, als Thomas Schissler erklärte, er habe anlässlich meines abendlichen Vortrags vor der UG Ulm eine Presseerklärung an die Zeitung geschickt. Und ich dachte schon, die Lokalpresse verfolgt mein Blog... ;-)

Ob der Artikel allerdings viel gebracht hat, weiß ich nicht. Die Kaffeehauskonsultation war auch ohne ihn 2 Wochen vor dem Termin schon "ausverkauft". Von 10h bis 17h gaben sich Entwickler die Klinke in die Hand und ich hatte Mühe, zwischendurch einen Happen zu essen. Aber passt schon. Hat wieder viel Spaß gemacht.


Links Thomas Schissler, rechts Andreas Gümbel, der sich mit mir darüber unterhalten wollte, wie er ein single-sign-on für mehrere Web-Applikation realisieren kann.

Auch der Vortrag am Abend in den Räumen von artiso fand vor einem vollen Haus statt.

Knapp 40 Entwickler waren gekommen, um sich einen Eindruck davon zu verschaffen, wie der Weg zur mehr Produktivität, besserer Testbarkeit, einfacherer Wartbarkeit und größerer Verständlichkeit ihrer Applikationen durch echte Komponentenorientierung aussehen könnte. Nach etwas mehr als 2,5 Stunden wussten sie es dann - hoffentlich :-) Denn solange habe ich doch für meinen Vortrag am Flipchart mit anschließender Demo in VS2005 gebraucht.

Die Kombination Kaffeehauskonsultation + UG-Vortrag - danke an INETA für´s Sponsoring - hat mir gut gefallen. Mache ich gern wieder.

Danke an Thomas Schissler für seine Initiatve! Das ist Nutzung der Angebote von Microsoft at its best.

Mittwoch, 21. März 2007

Vom Guten im Schlechten - TurboDb besser dank "Passionsspiele"

In der dotnetpro 4/07 hatte ich unter dem Titel "Passionsspiele" - passend zum Ostermonat ;-) - von meinem Leidensweg bei der Portierung einer .NET 2.0 Anwendung nach Mono berichtet. dnpMelodie, ein (noch und zugegebenermaßen rudimentärer) Windows Media Player/iTunes Clone, wollte ich mal eben so auf Linux umstellen, weil das aufgrund der komponentenorientierten Architektur einfach schien. Leider ging das aber daneben, weil Mono derzeit noch zu wenig kompatibel zu .NET 2.0 ist und... ja, und auch die Datenbank, von der ich dachte, das sie hüben wie drüben laufen würde, eben das nicht tat.

Ich hatte mich für die Neuentwicklung der Datenzugriffskomponente, die zunächst auf die Jet Engine ausgelegt war, für TurboDb von DataWeb entschieden. TurboDb Managed ist eine rein in Managed Code geschriebene Datenbank und sah für mich daher so aus, als sei sie der ideale Kandidat. Wie sich dann allerdings herausstellte, war TurboDb Managed nicht 100% kompatibel zu Mono. Leider hatte ich das aber erst gemerkt, als ich die Datenzugriffskomponente schon neu entwickelt hatte. War dann schade, aber machte auch nicht soviel. Ich hab es dann mit db4o nochmal probiert und die DB-Engine lief dann auch unter Mono - nur meine Anwendung trotzdem noch nicht.

Aber egal. Denn um die Inkompatibilität von TurboDb mit Mono geht es mir hier nicht. Nerviger waren vorher nämlich einige Stolpersteine während des Umbaus auf TurboDb unter .NET. Da funktionierte die SQL ORDER-BY-Klausel nicht wie mit der Jet Engine und ein Feldname war plötzlich ein reserviertes Wort und die Escape-Zeichen für solche Fällen waren schlecht dokumentiert. Davon habe ich dem Artikel im Sinne eines Entwicklungsprotokolls dann auch berichtet.

Und nun hat mich der Hersteller von TurboDb kontaktiert, nochmal genauer erfragt, was mein Problem war... und hat die Probleme behoben. Hier ein Auszug aus der Email von DataWeb:

Hallo Herr Westphal,

vielen Dank für Ihre Hinweise.

Bei der Sortierung haben Sie einen Bug entdeckt. Er betrifft Strings der Länge 1 in ANSI-String-Feldern (also nicht Unicode) der Länge 256 und darüber. Die Ursache liegt im Kompatibilitätscode zu alten Versionen, wo diese Felder nur bis 255 Zeichen lang sein durften. Der Fehler wird noch diese Woche behoben.

TurboDB Managed unterstützt Bezeichner in doppelten Anführungszeichen, wie es der SQL-Standard vorsieht. Das ist auch dokumentiert (im Kapitel über Spaltennamen) wenn auch zugegebenermaßen etwas unscheinbar. Wir haben aber auf Ihre Bemerkungen hin auch die eckigen Klammern ergänzt, wie sie in der MS-Welt üblich sind. Außerdem gibt es jetzt ein AddWithValue für die Parameterkollektion.

...

Das nenne ich prompte Reaktion! Toll! Danke, Herr Holzinger!

Und was lernen wir daraus? Ein bisschen maulen in der Öffentlichkeit hilft. Die Hauptaufgabe von technischen Artikeln ist natürlich zu zeigen, was geht. Aber wenn etwas nicht geht, sollte das nicht einfach stillschweigend mit einem Workaround verborgen werden, sondern durchaus auch in einem Artikel zu Kenntnis der Leser wie auch des Herstellers gebracht werden. Und Hersteller - insbesondere kleinere wie DataWeb - können Pluspunkte sammeln, wenn sie solche Hinweise ernst nehmen und Reaktion zeigen. Sie können damit einen Vorteil gegenüber den Platzhirschen ausspielen: ihre Agilität. Es heißt ja schon lange nicht mehr "Der Große schlägt den Kleinen", sondern auch "Der Schnelle/Flexible den Langsamen/Starren".

Also: Wer eine embedded Datenbank geschrieben in Managed Code sucht, der sollte einen Blick auf TurboDb Managed werfen. Man ist dort kundenorientiert. Das finde ich geiler als Geiz :-)