Views als Schnittstelle

Wenn man mittel Java oder PHP oder einer Programmiersprache deiner Wahl auf ein RDBMS zugreift, dann kann man Code erstellen, der sich ohne Umwege der Tabellen bedient. Man kennt den Namen der Tabellen und ihre Spaltenbezeichnungen. Dann ist fix eine Abfrage gecodet und – schwupps – erscheint das Ergebnis in der Anwendung. So weit, so gut, so einfach.

Kompliziert wird es, wenn Tabellen sich ändern – beispielsweise wegen Kundenanpassungen. Für den bereits bestehenden Code ist das nicht gut, denn der “wettet” ja auf eine ganz bestimmte Struktur. Beim Ändern der Tabelle müßte man also darauf achten, bestehenden Code nicht zu zerbrechen – was für eine Qual! Ich müßte den gesamten Code abklappern … gar nicht gut, das dauert viel zu lange und Chef sitzt mir im Nacken. Was tun?

Eine Option ist, den Quelltext so zu organisieren, dass mir das Abklappern leicht fällt. Aber das ist ein anderes Thema. Hier und jetzt möchte ich die Seite des RDBMS beleuchten. Kann mir das helfen? Natürlich kann es das.

Die mir bekannten RDBMS erlauben es, Views zu erstellen. Ein View kann man sich als benannte und im RDBMS gespeicherte Abfrage vorstellen. Das ist eine hilfreiche Option, dem Kind einen Namen geben zu können – hilfreich für das Verständnis, das Debuggen. Und man kann die Daten so bekommen, wie man sie braucht: Man kann weglassen, Spalten umbenennen, mit join arbeiten usw. – eben all die Techniken nutzen, die ein select bietet. Der View “kennt” die benötigten Tabellennamen, aber der Nutzer des Views braucht die beteiligten Tabellennamen und -strukturen nicht zu kennen. Der Nutzer des Views kennt – nur den View. Wie der View zu seinem Ergebnis kommt, ist dem View-Abfrager gleichgültig. In der Programmierung nennen wir dieses Prinzip “Kapselung”.

Auf der Seite der Client-Programmierung macht es keinen Unterschied, ob ich eine Tabelle abfrage oder einen View. Deswegen bietet das Erstellen von Views die Möglichkeit, eine stabile Schnittstelle aufzubauen. Feine Sache, weil der zugreifende Code nicht zerbrechen wird, wenn ich eine Tabelle ändere, die jenseits der Schnittstelle liegt.

Eitel Sonnenschein? Fast. Woher weiss ich, dass eine Tabellenänderung nicht Views kaputt macht? Hier hilft mir eine Automatisierung: Ich habe ein Script, das alle Views löscht. Und ich habe ein Script, das alle Views aufbaut. Wenn die beiden Scripte erfolgreich abgearbeitet werden können, dann ist’s in Ordnung. Wenn nicht, dann kann ich anhand der Fehlermeldung beim Anlegen genau sehen, was und wo es schiefgeht.

Offene Frage: Ist einfügen in und löschen aus Views möglich? Mit Oracle’s RDBMS schwant mir, dass es möglich ist, wenn der View “key preserved” ist. Mssql löscht einfach – und unter Umständen ist man überrascht, was da gelöscht wird und was nicht :-/

Offene Frage: Gibt es Views mit Parametern? Das wäre praktisch …

 

 

Veröffentlicht unter Allgemein | Verschlagwortet mit , , , | Kommentare deaktiviert für Views als Schnittstelle

Weihnachtsgeschäft

Es ist November, das Weihnachtsgeschäft soll’s ‘rausreissen. Also schicken wir denjenigen Kunden eine Ansichtskarte an die letzte Lieferadresse, die seit zwei Jahren nichts gekauft haben, aber davor wenigstens dreimal etwas geordert haben. Jetzt Du, Programmierer …

Hier ist ein Ausschnitt der (My)Sql-Tabellen-Struktur, gefüllt mit Fantasie-Daten. Ich habe es für MySQL entwickelt, es sollte mit keinen oder wenigen Anpassungen auf andere RDBMS übertragbar sein.

Zuerst finde heraus, wer wieoft bestellt hat und wann die letzte Bestellung stattfand – unter Bachtung der oben gegebenen Einschränkungen:

Aufgrund dieser Daten suche ich die Rechnungsadresse – mit einem self-join:

Und dann brauche ich das nur noch mit den Adressen zu verbinden und habe das Ergebnis:

Die Bestelldaten sind auch für Menschen überschaubar. Peter bekommt keine Karte, weil er ein treuer Kunde ist und wir hoffen, dass er in diesem Jahr auch so wieder etwas bestellt. Paul bekommt keine Karte, weil er – nach unseren Masstäben – kein Interesse hat. Erika ergeht es wie Peter. Aber eine Karte in Erna zu investieren lohnt bestimmt!

Aufräumen nicht vergessen, weil das nur ein Bespiel ist.

Und das SQL ist so, dass wir es im kommenden Jahr wieder verwenden können. Der Serienbrief-Druck kann beginnen.

Über den Sinn und Unsinn einer solchen Weihnachtskarten-Aktion kann man trefflich streiten. Erfolgskontrolle wird die Marketing-Abteilung freuen: Wer von den angeschriebenen hat wieder etwas bei uns gekauft? Und warum? War die Karte der Auslöser oder die Trennung vom Partner oder … was?

Veröffentlicht unter Allgemein | Verschlagwortet mit , , , , | Kommentare deaktiviert für Weihnachtsgeschäft

Vor einigen Jahren habe ich für den Mssql-Server herausgefunden, dass Abfragen mit “join” mehr als 100 mal schneller sein können als die gleich Abfrage in Form eines Subselects. Stimmt das auch heute für MySQL? Folgendes zeigt, dass es nicht zwingend so ist.

Frage: Welche Postleitzahlen gibt es sowohl in Deutschland als auch in den USA?

Stationen auf dem Weg zur Antwort:

  • Quelle von PLZ-dumps
    http://www.tutorials.de/relationale-datenbanksysteme/229059-postleitzahlen-mysql-dump.html
    => Einspielen in die Tabelle ‘orte’.

  • Quelle US Zip-Codes
    http://federalgovernmentzipcodes.us/free-zipcode-database.csv
    aufbereiten mit
    cut -d “,” -f2,4 free-zipcode-database.csv > free-zipcode-database-zip-city-only.csv
    Ergänzung für einen brauchbaren MySQL-Dump überlasse ich dem geneigten Publikum.
    => Einspielen in die Tabelle ‘orteus’.

  • SQL-Befehle übersichtlich strukturiert. Sie werden unten als 1-Zeiler benutzt:

    Copy&Paste aus dem mysql-Client:

    Ergebnis: Für ca. 44000×81000 ist fast kein Unterschied auszumachen.
    Ich bin angenehm überrascht. Einschränkung der Gültigkeit der Erkenntnis: Die Datenmenge im obigen Beispiel ist nicht gross. Damals bei Mssql ging es um ungefähr 12000×625000, also Faktor 0,5 aber immerhin diesselbe Grössenordnung.

  • Publiziert am von matthias | Kommentare deaktiviert für join vs subselect

    Besser nicht AppendItemValue

    In der Klasse NotesDocument in Lotus Notes 8 gibt es eine Methode AppendItemValue (itemName$, value). Zitat aus der API-Doku:

    If the document already has an item called itemName$, AppendItemValue does not replace it. Instead, it creates another item with the same name, and gives it the value you specify.

    Und es gibt NotesDocument.GetFirstItem ( name$ ). Zitat aus der API-Doku:

    However, the recommendation is that you avoid creating multiple items with the same name.

    Die Bedienungsanleitung von GetFirstItem legt also nahe, AppendItemValue nicht zu nutzen. Seltsam, dass so eine Situation entstanden ist.

    Für meine Aufgabe habe ich schließlich NotesItem.AppendToTextList ( value$ ) benutzt. Das zeigt eine Schieflage: Es gibt keine Möglichkeit, einen hinzugefügten Wert wieder zu entfernen.

    Also habe ich zwei Programmierungen ergänzt: Zum einen AppendTextToItemsTextlist ( name$, wert$ ) und zum anderen RemoveFromTextList ( wert$ ), jeweils in den entsprechenden Wrapper-Klassen.

    Veröffentlicht unter Allgemein | Verschlagwortet mit , , | Kommentare deaktiviert für Besser nicht AppendItemValue

    Feuerzungen

    Gegeben sei ein Webprojekt in nicht allzu ferner Zukunft, bei dem jetzt schon eingermassen klar ist, was gefordert wird – serverseitige Programmierung gehört dazu. Mit dem Glück, auf “der grünen Wiese” anfangen zu können, geht die Entscheidung für eine bestimmte Programmiersprache einher. Wie entscheidet man?

    Aus dem Bauch ‘raus

    Wenn man schon mit mehreren serverseitigen Web-Sprachen vertraut ist, dann kann man seinem Bauchgefühl nachgehen. Für diesen Entscheidungsweg spricht, dass er kurz ist – Zeit ist Geld. Und alles in allem wird man das Kindchen schon schaukeln, schließlich ist man Programmierer, gelle. — Was tun, wenn man noch keine oder nur eine Websprache spricht und dem Bauchgefühl misstraut?

    In dieser Umgebung

    Das Ziel, dass Dich wie der Polarstern führt, ist, den Job zu erledigen. Dein Programm wird auf einer Maschine ausgeführt – und die legt Dir mitunter Beschränkungen auf. Wähle eine Sprache, die vom Zielsystem unterstützt wird.

    Hier und Jetzt

    Mach’ Dir keine Gedanken darüber, wie es in X Jahren sein könnte. Kann sein, dass sich nichts ändert – ich arbeite gerade mit 10 Jahre altem php-Code und 15 Jahre altem Lotus Script. Kann sein, dass sich alles ändert. Man weiss es nicht. Sobald Du versuchst, auf alle Eventualitäten vorbereitet zu sein, kommst Du schnell vom Hundersten zum Tausendsten – und verlierst das oberste Ziel aus den Augen. Beachte die Sachverhalte, die in nächster Zukunft anstehen – geplanter Betriebssystemwechsel und neue Major-Releases der kritischen Komponenten. Wähle eine Sprache, die Dir Hier und Jetzt hilft.

    Übergabe-Punkte aka Schnittstellen

    Heute bringen serverseitige Programmiersprachen eine Vielzahl von Schnittstellen mit: zu Datenbanken, Verzeichnisdiensten, dem Dateisystem uvm. Beachte die Schnittstellen, die im Projekt gefordert werden und nicht im Standardumfang der Sprache enthalten sind. Beispiel Daten-Import von Buchführung, Controlling und Vertrieb, Daten-Export in ein proprietäres Tabellenkalkulations-Format. Gibt es dafür fertige Lösungen – und wenn ja, in welcher Sprache? Beachte nur die Schnittstellen, die das Projekt unbedingt braucht und die Du bezahlt bekommst. Wähle eine Sprache, die es Dir leicht macht, die notwendigen Schnittstellen zu bedienen.

    DRY

    Kann sein, dass der Kunde Komponenten mehrfach nutzen möchte. Zum einen erfüllen sie ihre Aufgabe im Internet. Zum anderen soll auch die Abteilung XY die Komponente nutzen, um diesselben Berechnung auszuführen. Wenn das eine Anforderung ist, dann wähle die Sprache, die es Dir leicht macht, diese Anforderung zu erfüllen.

    Die wichtigen Aufgaben so leicht wie möglich

    Ein Kriterium ist, dass die Sprache es Dir leicht macht, die grossen und zahlreichen Aufgaben mit wenig Aufwand zu lösen. Konkretes Bespiel: Der Htmlparser in python ist komfortabler zu bedienen als der in Java. Wenn ich absehen kann, dass ich viel Html-Daten verarbeiten muss, dann nehme ich also python. Natürlich kriege ich dasselbe auch in Java hin, aber das braucht dann mehr Zeit, weil ich mir Helferchen drumherum basteln muss.
    Gibt es bereits fertige Komponenten, die Du einbinden darfst und kannst?

    Babylon

    Schiebe die Entscheidung für die Implementierungssprache lange auf. Entwickle die Konzepte zuerst in UML. So lernst Du die Anforderungen gut kennen. Wenn Du eine Anforderung verstanden hast, dann mach’ Dich auf die Suche nach einer Sprache, die es Dir einfach macht, diese Anforderung zu erfüllen. Richte Dein Augenmerk auf die komplizierten Anforderungen. Am Ende hast Du eine Liste mit Paaren von Anforderung und Sprache. Wie oft kommt welche Sprache vor? Wie wichtig ist die Anforderung? Strich drunter, Zusammenzählen, entscheiden.

    Deine Freundin Juno

    Du brauchst eine gute IDE, Beispiel Eclipse Juno (Stand 2012) für Java. Du brauchst einen Debugger. Du brauchst Dokumentation. Du brauchst einen automatisierten Build-Prozess. Du brauchst Tests. Wähle eine Sprache, die Dir das ‘drumherum leicht macht.

    Java, Perl, PHP

    Ich mag stark getypte Sprachen lieber als schwach getypte, weil ich damit unkompliziert erkennen kann, welche Art von Daten gerade bearbeitet werden. Bei Refactoring und Reengineering ist das Gold wert. Java ist meine Brot-und-Butter-Sprache, da geht immer ‘was, da kenne ich Tricks und Fallstricke, das mache ich seit n+1 Jahren. Wegen Perl sind mir schon viele graue Haare gewachsen – das lag aber wohl mehr daran, wie der Code strukturiert war als an der Sprache selbst. In PHP kann man erträglich objektorientiert entwickeln – der entstehende Code ist leider nicht hübsch. Perl und PHP sind ganz ok, aber nicht meine erste Wahl.

    Ruby (on Rails)

    Mit Ruby habe ich noch nie gearbeitet, aber die Texte auf der Website sind sehr vielversprechend. Es gibt eine grosse Menge Zusatzmodule und Ruby On Rails – “optimized for programmer happiness” – wenn das kein Versprechen ist! Habe den Quelltext von “omniauth 1.1.4″ überflogen – sehr hübsch! Augenfreunlich :-) Habe das “Getting started” durchgearbeitet. RoR ist toll. Zwar war die Installation auf meinem System nicht ganz so einfach, wie es die Anleitung nahe legt, aber schließlich schlage ich mich mit sowas schon lange herum – also kein echtes Problem. Einige Code-Stellen von “Getting startet” werfen Fehler auf meinem System, aber auch das ist mit Erfahrung und duckduckgo in den Griff zu kriegen. Habe einen Blick auf die API-Doku geworfen, um einem Fehler auf den Grund zu gehen – bin damit spontan zurecht gekommen. Ich bin RoR-kompatibel ;)

    Es gibt nicht “die beste Sprache”. Es gibt aber die Sprache, die Dir bei Deinem Projekt am besten dient. Nutze die Chance, eine neue Sprache kennenzulernen und riskiere Verzögerungen wegen Unkenntnis und kindlich-putzige Konstrukte. Nutze Deine Muttersprache und riskiere Verzögerungen wegen Radneuerfindung.

    Veröffentlicht unter Allgemein | Kommentare deaktiviert für Feuerzungen

    Zu den Sherlock-Holmes-Geschichten habe ich ein gespaltenes Verhältnis. Ich mag die Charaktere, die Rätsel, den Sieg der Vernunft. Und mit Vernunft hängt zusammen, was ich nicht mag: Nur Holmes kennt _alle_ Zusammenhänge – das macht es dem Leser unmöglich, selbst hinter das Geheimnis zu kommen. Im Laufe der Geschichte offenbaren sich immer mehr Details, und das letzte Puzzelteilchen setzt der Superdetektiv persönlich ein. Der Leser kann nur “zuschauen”.

    Wartungsprogrammierung ist anders. Alle Fakten liegen vor. Kann sein, dass der Quelltext schwierig zu lesen ist. Kann sein, dass es sehr viel Quelltext ist. Kann sein, dass ich lange brauche, um alle relevanten Fakten zu kennen. Aber so seltsam das Verhalten einer Software auch anmuten mag: Es beruht auf Vernunft, es folgt den Regeln der Logik. Das ist beruhigend, weil unumstößlich fair. Es gibt da keinen Deus ex machina, keinen, der Dir hilft, und keinen, der Dich behindert.

    Ich habe lange in einem Büro gearbeitet, an der Wand ein grosses Bild von Dr. House’s Kopf mit dem Spruch “Menschen lügen. Code nicht.” Kommentare im Quelltext sind manchmal offensichtlich falsch, ein anderes Mal führen sie Dich unbemerkt auf eine falsche Fährte. Die Namen von Funktionen-Methoden-wie-immer-Du-es-nennst-Du-weisst-was-ich-meine können in die Irre führen. Variablennamen können Fehlverstehen fördern.

    Wartungsprogrammierung bedeutet zuerst, sich zum Kern dessen vorzuarbeiten, was im Programm geschieht, ohne sich von den Worten ablenken zu lassen. Das ist wie im wirklichen Leben: Ich kann begreifen, was ein anderer mir mitteilen möchte, auch dann, wenn er unpassende Worte nutzt. Wenn man beispielsweise versucht, mit Fremdworten zu imprägnieren, dann kann das erfolglos bleiben – beim Imprägnieren. Auf der Sachebene aber kann die richtige Botschaft ankommen. Wartungsprogrammierung endet damit, dass Veränderungen vorgenommen werden. Syntaktisch-semantische Objektivierung folgt intentionaler Digital-Hermeneutik ;)

     

    Publiziert am von matthias | Kommentare deaktiviert für Sherlock Holmes

    Malen mit Zahlen

    Ich habe Schlachten geschlagen, das Gesicht vernarbt, der Gang schleppend. Die Arme stecken in einem undurchsichtigen Sumpf aus pechschwarzzähem Altöl, die Finger geraten da unten in das Getriebe, das ich nicht sehen kann – ab. Die Sonne brennt den Himmel weiß. Verschmiert und durstig stolpere ich Schienen entlang, die sich mit ingenieurischer Präzision durch die ockerfarbene Ebene ziehen, bis an den Horizont.

    Das meine ich ernst – und bildlich, nicht wörtlich. Wir verstehen die bildliche Rede des Gegenübers im Alltag meistens ohne grosse Anstrengung: “Irgendwie schmerzhaft und trostlos, dazu ein bißchen Pathos”. Funktioniert vermutlich am besten, so lange man sich der Muttersprache bedient und den eigenen Kulturkreis als Grundlage der Interpretation benutzen kann. Wenn ich französische Comics und Zeitungen lese, dann flutschen mir fast alle Metaphern durch – will sagen: ich nehme wörtlich, was bildlich gemeint ist. Mißverständnisse sind mitunter sehr erheiternd.

    Das oben beschriebene Bild kam mir, nach dem ich sehr lange sehr … häßlichen … Code bearbeitet hatte.
    Exkurs: Oft ist es verlockend, Metaphern zu benutzen – eine Abkürzung, die die Eindringlichkeit nicht verliert. “Häßlich” zu sagen ist einfacher, als all das aufzuzählen, was jenseits der Ästhetik liegt. Nur ein fauler Programmierer … Welche Eigenschaften machen Code zu häßlichem Code? Unlesbarkeit, Unverständlichkeit, Brüchigkeit – Änderungen an einer Stelle sorgen für schwerwiegende Fehler an einer anderen Stelle, die “weit entfernt” ist. Code, der wie ein Text von Hegel ist – bildlich gesprochen gibt es das! Oder scholastisch – mit vielen Wenns und Abers. Klugscheisser mag kein Mensch. Exkurs-Ende.

    Wenn ich eine neue Programmiersprache lerne, dann ist in meinem Kopf das Bild von mir als kleines Kind, das im Matsch eine Burg baut. Das rote Schüppchen liegt nahe bei, Hose und Hemd nass und zugeferkelt, Haare und Gesicht voll verkrustetem Schlamm. Die Burg ist nur mit viel elterlichem Wohlwollen oder Phantasie als solche zu erkennen. Nicht effektiv, nicht effizient, nicht von Dauer, Muttern hat wieder Arbeit mit der Wäsche. Nur eins: Ein riesengrosser Spass, der glückliches Lächeln zaubert. Die ersten Zeilen Quelltext in der neuen Sprache sind eine Matschburg.

    Putzfimmel

    In meinem Handapparat steht das Buch “Clean Code”[2]. “Sauberer” Code ist kein häßlicher Code. “Sauberer” Code ist modular und wiederverwendbar, einfach zu testen, einfach zu ändern, robust, seine Zusammenhänge und Wege lassen sich mühelos offenlegen. “Sauber” ist hier eine Metapher. Mit “sauber” verbinden wir angenehmes und gesundes. Weil Metaphern oft so eindringlich sind, kann man leicht vergessen, darüber nachzudenken – man nimmt sie eben so hin. Denk’ ‘mal an “saubere Trennung” und “Säuberung”. Klingt doch gut, oder. Ja, aber oft hängt damit Schönrederei zusammen. Pars pro toto: Sei Dir bewußt, dass Du Metaphern benutzt. Reflektiere Deine Metaphern gelegentlich. Lass’ Dich von Deinen Metaphern nicht verführen.

    Man sollte Metaphern nicht überstrapazieren. Beispiel: Was bekommt man, wenn man “jeden Dreck” entfernt, alles “blitzblank” programmiert, die Sauberkeit auf die Spitze treibt? Der Quelltext hat dann keine “dunklen Ecken” mehr, keine Stellen, bei denen man Gefahr läuft “einen Finger zu verlieren”. Man bekommt keinen keimfreien Code, sondern nur sauberen – die Sauberkeits-Metapher “trägt” hier nicht mehr, sie hilft uns nicht mehr weiter.

    Jedes Ansammlung von Quelltext, die mir bisher untergekommen ist, hat “dunkle Ecken”. In der Software-Entwicklung nennt man eine dunkle Ecke “Anti-Pattern”, im Gegensatz zu den “Design-Patterns” der Gang-Of-Four. Leicht verfällt man in Sauberkeitswahn und will alle Anti-Patterns ausputzen. Ich denke heute, dass es falsch ist, eine Neurose hinsichtlich unsauberen Codes zu entwickeln – oder Verhalten zu fördern, das zu einer solchen führt. Neue Programmteile programmiere ich so gut wie möglich. Alte säubere ich, wenn sie in Zusammenhang mit den neuen stehen und – wichtige Einschränkung – mir die Kontrolle des neuen in der Folgezeit erheblich erschweren werden. Schmuddeligen Code sehe und bewerte ich und lasse ihn vorbeigehen, wenn er unwichtig ist. Augenmass ist wichtig.

    Das Huhn im Topf

    Woran denkst Du, wenn Du “Spaghetti” hörst? An die Anstrengung, sie zu produzieren? Das Paket im Supermarktregal? Oder “carabonara” – gleichauf “bolognese”? Ich kenne keine Studie dazu, aber ich wette, die meisten denken an carabonara/ bolognese. Und haben ein Bild vor Augen, das dem der Wikipedia bei “Spaghetticode” nahe kommt. Denken und Sprache hängen eng zusammen, genauso Denken und Sehen. “Sehen ist glauben”. “You don’t think so? We’ll see.” Spaghetticode ist häßlich, weil verworren. Ich mag Spaghetti-Code: Er sichert mein Auskommen bis zur Rente. Meine Finger hat die Maschine eh’ schon gefressen ;)

    Ich habe schon viel Quelltext gesehen – gelesen, durchgeackert. Und viel davon hatte eine je eigene Handschrift. Kommentare, Variablennamen, die Weise der Klammerung, die Aufteilung der Funktionen – das unterscheidet sich von Programmierer zu Programmierer. Einen Eindruck hinterläßt bei mir jeder Code – den sinnlich wahrnehmbaren. Sauberer Code, schöner Code, guter Code – Dem Wahren, Schönen, Guten. Code und Ästhetik. Ich bemühe mich so zu programmieren, dass das Ergebnis ein Jungbrunnen ist, Ambrosia. Auf dass es geschmeidig ineinander greift, wie ein Schweizer Uhrwerk.

    Licht

    All das, was wir heute mit PCs treiben, ist in unserer Wahrnehmung Lichtjahre entfernt von Schalter-an-Schalter-aus, von 0 und 1, von den grundlegenden Funktionen einer Rechenmaschine. Und doch ist es faktisch genau nur das. Das “Blech”, der “Maschinenraum” des PCs liegt unter etlichen Metapher- Schichten. Mein ehemaliger Kommilitone Dieter J. – Programmierer und SysAdmin – sagte mit einem Augenzwinkern: “Wir sind Magier und haben die Zaubersprüche für die Geister, die in den kleinen schwarzen Kästchen eingesperrt sind.” A.C. Clarke: “Jede ausreichend fortgeschrittene Technologie ist von Zauberei nicht zu unterscheiden”[1]. Damit hält die Mystik wieder Einzug in den Alltag. Einerseits ist es ja ganz angenehm, nicht nur ständig mit “kühler Technik” in Berührung zu kommen. Andererseits möchte ich dringend dazu raten, einen Artikel über Halbaddierer zu lesen[4]. Man kann den PC vermenschlichen, als Abkürzung für technische Details – aber bitte nicht ernst nehmen. Alles, was Du auf dem Bildschirm siehst, ist eine gigantische Ansammlung von 0 und 1.

    Programmierern (-lernen) heißt heute, sich in den geekisch-nerdischen Kulturkreis einzufinden, so dass einem die gängigen Metaphern[3] verständlich werden.

    [1] http://www.oreilly.de/opensource/magic-cauldron/cauldron.g.magic.html
    [2] Robert C. Martin. Clean Code. A Handbook of Agile Software Craftsmanship. Boston, 2009.
    [3] Möglicher Ausgangspunkt http://de.wikipedia.org/wiki/Jargon_File
    [4] Beispielsweise Gumm, H.P./ Sommer, M.: Einführung in die Informatik. 6., vollständig überarbeitete und erweiterte Auflage. München, Wien 2004. S.431ff

    Veröffentlicht unter Allgemein | Verschlagwortet mit , , , , , | Kommentare deaktiviert für Malen mit Zahlen

    Beispiel Portokosten

    Machen Sie sich keine Sorgen, wenn Sie dieses Buch nicht gleich beim ersten Lesen vollständig verstehen. Wir haben beim ersten Schreiben auch nicht alles verstanden! — [GOF], xiii

    Stell’ Dir einen Versandhandel vor. Von einem Kunden geht eine Bestellung ein, die lieferbaren Posten werden ‘rausgesucht, eingepackt und verschickt. Wie wird das Porto berechnet? Dazu gibt es eine Vereinbarung, die sinngemäß diesen Inhalt hat:

    1. Nachnahme-Sendungen kosten 4,70 Euro zusätzlich. Hier werden keine Ausnahmen gemacht.
    2. Bei Lieferungen mit einem Wert über 49,99 Euro wird kein Porto berechnet. Ausnahme sind Eintrittskarten, s.u.
    3. Eintrittskarten werden immer versichert versendet. Die Versicherung kostet 4 Euro, unabhängig von der Anzahl der Karten.
    4. Der Wert der Eintrittskarten in einer Bestellung trägt nicht zum Wert bei, aufgrund dessen das Porto berechnet wird.

    Meine Aufgabe: Programmiere das, so dass erstens der Kunde abfragen kann, welche Kosten auf ihn zukommen und zweitens der Packer sich keine Gedanken machen muss.

    Der einfache Teil der Analyse

    1. Es gibt Waren. Regel “Substantive werden zu Klassen”. Also erschaffe ich eine Klasse “Ware”. Eine Ware hat Name und Preis – den Rest blende ich für dieses Beispiel aus.
    2. Eine Eintrittskarte ist eine Ware, verhält sich aber ein bisschen anders. Also erschaffe ich eine Klasse “Eintrittskarte”, die von “Ware” erbt.

    Damit ist der einfache Teil zuende. Jetzt kommt der philosophische.

    Diskussion

    Ist es gut, eine Methode “holeVersicherungskosten” für die Klasse “Ware” zu erschaffen? Vorteil, dass ich für eine Ware den Wert 0 zurückgeben kann – einfach und deswegen gut. Und für eine Eintrittskarte überlagere ich die Methode und gebe was zurück? Den Wert 4? Nein, nicht immer, denn nicht jede Eintrittskarte kostet 4 Euro Versicherung, sondern alle Eintrittskarten zusammen. Die eine Eintrittskarte weiss aber nichts von anderen ihrer Art. Der Aufrufer könnte sich merken, ob er schon mal ein Eintrittskarte “in der Hand” hatte, also bei jedem Aufruf das jeweilige Objekt nach seiner Klasse fragen – das ist sehr unelegant. Und ja: Eleganz ist ein wichtiges Kriterium für guten Code. Und ganz sicher will mein Chef guten Code. Wenn er das nicht will, dann wird er nicht lange mein Chef bleiben – und ausserdem ist das hier aysx. Hier wird guter Code gemacht. Zurück zum Thema: Ich komme so nicht weiter. Weil “holeVersicherungskosten” nicht sinnvoll ist für die Klasse “Eintrittskarte” und ich “Ware” und “Eintrittskarte” austauschen können möchte, verbietet es sich die Methode “holeVersicherungskosten” für die Klasse “Ware”. Dieser gerade-heraus-Ansatz ist für die Eintrittskarten-Versicherung also eine Sackgasse. Na, mache ich halt an der anderen Stelle weiter.

    Ist es gut, eine Methode “holeLieferungswertPortoGrenzenBeitrag (n)” für die Klasse “Ware” zu erschaffen? Das scheint vielversprechend: Eine Ware gäbe dann ihren Preis multipliziert mit n zurück und eine Eintrittskarte gäbe immer der Wert 0 zurück. Selbst wenn der Auftraggeber auf die Idee kommt, eine neue Kategorie von Ware einzuführen, die nicht in das bestehende Schema passt, bin ich fein ‘raus: Die neue Klasse erbt von “Ware” und implementiert eine eigene Methode “holeLieferungswertPortoGrenzenBeitrag (n)”. Bin ich jetzt wirklich fein raus? Nein. Warum? Weil der Auftraggeber auf die Idee kommen wird, dass für bestimmte Waren neue Regeln gelten. Und wenn diese neuen Regeln dazu führen, dass ich neue Methoden einführen muss, dann habe ich eine Menge Arbeit. Das geht mir gegen den Strich. Nur ein fauler Programmierer ist ein guter Programmierer – Du darfst mich gerne zitieren. Zurück zum Thema: die Idee mit “holeLieferungswertPortoGrenzenBeitrag (n)” ist eine Sackgasse.

    Wie wäre es, wenn es ein Dingsbumms gäbe, das die Berechnung der Versicherungskosten kennt? Na gut, aber woher soll das Dingsbumms wissen, welche Berechnung auszuführen ist? Nun, die Ware oder Eintrittskarte – je nach dem, was gerade da ist – “sagt” es dem Dingsbumms. Das Dingsbumms wird sich gefälligst merken, ob es schon einmal von einer Eintrittskarte aufgerufen wurde, damit die Versicherung nur einmal berechnet wird. Und ausserdem weiss es, dass “normale” Waren diesbezüglich keine Kosten erzeugen.

    Wie wäre es, wenn es zusätzlich ein Dingsda gäbe, das die Berechnung des Portofreigrenzen-Beitrags übernimmt und das auch von dem jeweiligen Objekt gesagt bekommt, was zu tun ist? Also so ähnlich wie ein Dingsbumms, aber bei den Berechnungen anders. Ich führe jetzt eine Abkürzung ein: Dingsda und Dingsbumms sind BerechnungsDings.

    Mit BerechnungsDings werde ich den neuen Anforderungen gerecht. Was passiert, wenn der Auftraggeber eine neue Warenkategorie wünscht? Nicht viel! Ware und Eintrittskarte können bleiben, wie sie sind. Vielleicht müssen Dingsbumms und Dingsda verändert werden – abhängig davon, welche Regeln für die neue Warenkategorie gelten. Und was muss passieren, um eine neue Regel einzuführen? Auch nicht viel! Ich muss ein neues BerechnungsDings erschaffen, vielleicht ein NurMitKreditkarteBezahlbarDings.

    Heureka!

    In der Software-Entwicklung nennt man das BerechnungsDings “Visitor”, Besucher. Der Visitor hat etwas, das er besucht – hier Ware und Eintrittskarte. Damit der Visitor bei den beiden vorbeischauen kann, stellen Ware und Eintrittskarte je eine Methode zur Verfügung, die meistens “accept” benannt wird. Die Methode hat einen Parameter – den Visitor selbst. Damit der Visitor auf unterschiedliche Objekttypen unterschiedlich reagieren kann, stellt er für jeden Objekttyp eine Methode bereit, deren Name mit “visit” beginnt und mit dem Objekttypen-Namen endet – hier also “visitWare” und “visitEintrittskarte”. Die Visit-Methoden haben einen Parameter, nämlich das zu besuchende Objekt. Ablauf: Die Ware “akzeptiert” den Besucher. Sie ruft bei dem Besucher die für ihre Klasse passende Methode auf und gibt ihre Daten mit. Darauf hin wird der Besucher tätig, hier wird er beispielsweise den Preis abfragen oder ganz untätig bleiben – je nach dem, welche Regel er abbildet.

    technische Umsetzung

    Ein Interface “WarenVisitor” definiert, was so ein Visitor kann – Ware und Eintrittskarte besuchen. Im Gegenzug akzeptieren Ware und Eintrittskarte jeweils einen WarenVisitor und rufen die passende Methode auf. Vom WarenVisitor gibt es zwei Implementierungen, einen für die PortoFreibetrags-Berechnung, einen für die Versicherungs-Kosten. Das Klassendiagramm zeigt die Zusammenfassung. Die Implementierung ist trivial.

    portofrei

     Entia non sunt multiplicanda sine necessitate

    Mehr Klassen – ist das der richtige Weg? Hier ist er es, weil ich hier beides bekomme: Flexibilität und Stabilität. Der Visitor-Weg erlaubt, beliebiges Verhalten hinzuzufügen, ohne bestehendes Verhalten zu verändern. Die “Geschäftsklassen” Ware und Eintritsskarte bleiben unverändert und ich kann ihnen “hinter den Kulissen” neues Verhalten unterjubeln.

    Literatur

    [GOF] Gamma, E./ Helm, R./ Johnson, R./ Vlissides, J.: Entwurfsmuster. Elemente wiederverwendbarer objektorientierter Software. 5., korrigierter Nachdruck, Bonn 2003. (GOF steht für “Gang-Of-Four”. Das Buch ist ein Quell steter Freude. Im Zweifel: kaufen.)

    Veröffentlicht unter Allgemein | Verschlagwortet mit , , , | Kommentare deaktiviert für Beispiel Portokosten

    Prosophie, Philogrammierung, dingsda …

    Language shapes the way we think,
    and determines what we can think about. — B. L. Whorf

    “The time has come,” the Walrus said,
    “to talk of many things.” — L. Carroll

    zitiert nach Stroustrup, B.: Die C++-Programmiersprache. 4., aktualisierte und erweiterte Aufl., München, 2000, S. xix, 3

    Ich nahm das Buch kürzlich in die Hand, weil es für mich lange Zeit das Gegenteil vom Handbuch der Java-Programmierung war. Das erste und einzige Buch, das ich aus Empörung an die Wand gepfeffert habe. Mein Fehler: Ich habe mir nicht genug Zeit genommen, war zu ungeduldig.

    Software-Entwicklung und Philosophie

    Bei den Chemikern stinkt es, bei den Physikern kracht es, Biologen zerschippeln Frösche, Soziokraten hantieren mit Statistiken, Maschinenbauer gehen auf Parties. Die Liste dieser Klischees läßt sich leicht fortführen.
    Ich habe – in Gesprächen mache ich hier eine kleine Pause – Philosophie studiert. Meine Mutter weiss bis heute nicht, was ich während dieser Zeit getrieben habe und wie und warum ich nun meinen Lebensunterhalt mit Software-Entwicklung bestreiten kann. Ich will versuchen, das zu erklären.

    Viele meinen, Philosohpie befasse sich nur mit der Frage nach dem Sinn des Lebens. Ganz ehrlich: Das ist nur eins dieser Klischees. Ein “echtes” Themen in der Philosophie ist die Frage nach der Begründbarkeit von Moral und Gesetz – wer politisch interessiert ist, dem wird die Notwendigkeit der Antwort einleuchten. Ein anderes “echtes” Thema nennt sich “kausale Referenztheorie”, erdacht von Hilary Putnam. Der amerikanische Philosoph bemüht sich in diesem Zusammenhang um die Klärung, was denn die Bedeutung der Bedeutung eines Wortes sei – das wird bei den meisten Menschen auf Unverständnis stoßen. Sei’s ‘drum. Klar sollte sein, dass es eine Fülle von Themen jenseits der gängigen Vorurteile gibt.

    Woher wissen wir von dieser Themenfülle? Ganz einfach: die Themen füllen Bibliotheken. Da ist es offensichtlich, dass Lesen eine der Hauptbeschäftigungen der Philosophologen – auf deutsch: Philosophie-Wissenschaftler – ist. Lesen allein genügt aber nicht, man muss es auch verstehen. Verstehen ist meistens nicht ganz einfach, also macht man sich Notizen, um hinterher mit anderen Philosophologen darüber reden zu können. Das Verfahren mündet dann in einem Aufsatz oder einem Buch. Das Werk stellt man in die Bibliothek und hat ‘was zum Lesen. Ziemlich gerissen. Aber das nur nebenbei.

    Als Philosophologe merkt man bald, dass die meisten Philosophen nicht nur gerissen, sondern auch rotzfrech sind. Zum einen sehen ihre “Antworten” oft aus wie Taschenspielertricks. Zum anderen haben sie keinen Respekt – nicht vor der Obrigkeit, nicht vor ihren Vorgängern. Sie ecken an und quengeln gerne. Das hört sich negativ an, ist es aber nicht. Ganz im Gegenteil: Sie denken eigenständig und pragmatisch. Das färbt ab. Heute sind das gefragte Soft-Skills.

    Die philosophisch lohnenswerten Themen sind nicht ganz so offensichtlich wie die von Naturwissenschaft und Technik. Ich will ein Beispiel geben und versuchen, Dich damit so zu verstören, wie ich damals verstört war, als man mich auf dieses hier stieß: Träume erscheinen einem oft ganz und gar wirklich, so lange man träumt – das hat sicher jeder schon erlebt. Unsere Augen täuschen uns – im Flimmern der Sonne auf dem Asphalt sehen wir Dinge, die nicht da sind. Einmal ist das Wasser aus der Leitung eiskalt, einmal ist dasselbe Wasser angenehm warm – das hängt davon ab, wie warm unsere Hände sind. Die Ohren – ich kenne jemanden, der in der weiten Stille Norwegens Feengesänge hörte. Kurz: Unsere Sinne sind keine Garanten für sicheres Erkennen. Gibt es überhaupt irgendetwas, dessen ich mir unumstößlich gewiss sein kann? Etwas, worauf ich all meine Erkenntnisse und mein Wissen bauen kann – ein solides Fundament? Mit dieser Frage schickte uns der Philosophie-Lehrer ins Wochenende.

    Einer der ganz frühen Philosophen ist Platon. Auf die Dauerbrenner-Frage “Wie kann ich etwas ganz sicher wissen?” antwortet er mit seiner “Ideenlehre”. Deren Details kann man anderswo lesen. Der interessante Punkt für den Software-Entwickler ist: Ideenlehre und Objektorientiert Programmierung sind strukturell gleich. Platon nennt es “Idee”, ich sage dazu “Klasse”. Platon sagt “Ding” oder “Schatten”, ich sage “Objekt”. Platon meint, dass jedes Ding die Verwiklichung einer Idee sei. Ich beschreibe eine Klasse und später erzeuge ich daraus Objekte – beliebig viele und alle von einander unterscheidbar. Wenn ich ganz sicher wissen will, wie mein Programm “tickt”, dann liegt die Antwort in den zugrundeliegenden Klassen. Die Parallele ist offensichtlich.

    Beispiele für andere Gemeinsamkeiten: Wer das Traktat des frühen Wittgenstein beackert hat, dem wird es ganz natürlich erscheinen, dass der Erfinder der Programmiersprache C++ davon schwärmt, Strukturen in Hierarchien abzubilden. Wittgenstein – Stroustrup. Philosoph – Programmierer.
    Naom Chomsky ist Geisteswissenschaftler und Informatiker. Wer sich mit Chomsky’s Klassifizierung von Sprachen befasst hat, dem ist klar, was Compiler leisten können und was nicht. Mit diesem grundlegenden Verständnis ist es ein leichtes, XML zu transformieren, und das ist eine Technik, die man immer wieder gut gebrauchen kann.

    Ein Philosoph erklärt Dir nicht die Welt im grossen und ganzen – das ist wieder nur ein Klischee. Ein Philosoph bemerkt allgemeingültige Strukturen für einen sehr kleinen Bereich der Wirklichkeit. Und das ist die Aufgabe eines Software-Entwicklers: Finde eine verallgemeinerbare Möglichkeit, einen kleinen Bereich der Arbeitswelt zu strukturieren. Ein gutes Programm meistert genau eine Aufgabe, nämlich die, für die es geschaffen wurde. Kann sein, dass Du das Programm nicht gebrauchen kannst, weil Deine Arbeitswelt eine andere ist. Ein guter Philosoph beantwortet genau eine Frage, nämlich diejenige, die ihm unter den Nägeln brennt. Kann sein, dass Du damit nichts anfangen kannst, weil Deine Frage eine andere ist. Die Parallele ist offensichtlich.

    Viele meinen, Programmieren sei nur das Eintippen von Anweisungen und haben das Bild eines ungepflegten, verschrobenen Nerds vor Augen, dessen Finger über die Tastatur fliegen. Klischee. Besser stellt man sich das ungefähr so vor: Ich rede mit den zukünftigen Benutzern und lese viel zu dem jeweiligen Thema. Ich bringe das Wissen und die Ideen zu Papier, strukturiere sie. Wieder und wieder reden, lesen, neu strukturieren, Details hinzufügen. Irgendwann ist es soweit, dass ich keine neuen Fragen mehr habe und User mich im Gespräch nicht mehr mit neuen Details überraschen können. Das Eintippen ist eine Kleinigkeit – die Vorarbeit ist viel schwieriger und umfangreicher.
    Und den allergrößten Teil der Arbeitszeit verbringe ich nicht damit, etwas neues zu erschaffen. Zu mehr als 80% behebe ich Fehler und baue kleine Erweiterungen an – man nennt das Wartungsprogrammierung.

    Kurzum …

    Ein Studium, bei dem reden, zuhören und argumentieren einen wesentlichen Teil ausmachen, ist eine gute Basis für den sozialen Prozeß, den wir “Software-Entwicklung” nennen. Ganz zu schweigen vom Schreiben – das nennt man “Dokumentation”.
    Ein Studium, das zu einem Drittel daraus besteht, sich in die Gedanken anderer einzufinden, bereitet gut darauf vor, fremden Programmtext zu lesen, zu verstehen und so zu verändern, dass die Funktionalität erhalten bleibt. So bestreite ich meinen Lebensunterhalt.

    Epilog

    Wer gegen Philosophie und Philosophiewissenschaft den Vorwurf erhebt, das sei alles nur nutzloses Geschwätz, den verdächtige ich, auch Vinologie, Bierologie und Haute Cuisine für überflüssig zu halten. Hauptsache besoffen und satt?!? Was für eine triste Welt. Wie grau muss die Gedankenwelt derer sein, die Philosophie “und das ganze Zeugs” ablehnen. So möchte ich nicht leben. Denn eins ist unumstößlich sicher: Ich denke, also bin programmiere ich.

    Veröffentlicht unter Allgemein | Verschlagwortet mit , , | Kommentare deaktiviert für Prosophie, Philogrammierung, dingsda …

    Symmetrie ist ein Meta-Prinzip in der Software-Erstellung. Im SQL-Warenkorbanalyse-Beispiel schrieb ich vorhin “Das sind die Paarungen, die vorkommen. Was ist mit denen, die nicht vorkommen?” Als ich die vorkommenden Paarung selektierte, schwante mir schon, das ich die anderen auch brauchen werde.

    Wenn ich etwas programmiere, das Daten ‘reinpumpt – wohin auch immer – dann mache ich mir auch Gedanken dazu, wie die Daten wieder gelöscht werden können. Datensatz sperren – entsperren. User kann Objekt schaffen – User kann Objekt zerstören. Undo – Redo. Verschlüsseln – Entschlüsseln. Film starten – anhalten. Und so weiter, und so weiter.

    In den meisten Fällen ist es hilfreich, jeweils beides einzubauen oder benutzen zu können. Bei Objekt-Orientierter Analyse und Design kann man darüber diskutieren, ob zu jedem Getter auch ein Setter implementiert werden soll, siehe https://en.wikipedia.org/wiki/Immutable_pattern. Ich habe mir in all den Jahren angewöhnt, auch an das Gegenteil, den Rückweg, die andere Seite der Medaille zu denken. Wenn ich das recht erinnere, dann war es eine Kollegin im MaDiN-Projekt, die mich darauf stieß. Seitdem beachte ich Symmetrie.

    Publiziert am von matthias | Kommentare deaktiviert für Symmetrie