Kategorie: Programmierung

Exception Handling in Multi-Layered Systems

This is the first blog post here which is completely in English. And of course there is a reason for that. I currently don’t plan to do this regularly (maybe I should? I don’t know.). Anyway, here is the reason: Next week I’ll give a talk for the Australian Delphi User Group in Sydney. The talk will be a webcast, which means, I’ll stay here in Germany while the audience will be sitting on the other side of the globe. ADUG members who cannot be in Sydney can also attend using the web streaming system.

What am I talking about? If you are reading my blog, you should recognise the topic:

Title: Exception Handling in Multi-Layered Systems
Abstract (or maybe I should rather say “teaser” or something):
How do you structure software properly? Why should we think about the structure of a software? And how? How to handle exceptional cases? Is the Exception language feature always the best way? This talk has roughly two parts. In the first part we will have a look at architecture, layers and tiers. The second part deals with exceptions and how to use them properly. In the end we will see what the one has to do with the other.

Errata:

  • There is a typo on slide 17: it should read “defines” instead of “defined”.
  • Slide 22 is not translated (sorry for that). The note there means “Weak layering: Layer 3 may directly access Layer 1.”

This is basically the same talk I gave at the Delphi-Tage this year in Heidelberg. After my presentation in Heidelberg, Mathias Burbach, the president of the ADUG, approached me and asked if I could also give this talk in English. And so I do. The contents will be basically the same, although there are some minor changes.

Again there are slides and more elaborate talk notes:

Download: Exception Handling in Multi-Layered Systems (Slides) (Größe: 3.08 MB; bisher 97 mal heruntergeladen)
Download: Exception Handling in Multi-Layered Systems (talk notes) (Größe: 3.08 MB; bisher 171 mal heruntergeladen)

I haven’t had the time to translate everything, so the German talk notes are still more detailed (roughly eight pages more).

While translating, I also realised that by now I’m already more used to American English than the British one. In school I mainly learned the British version but in university I almost exclusively hear, talk, read and write AE. Wikipedia says Australian English is pretty much like BE, so I’ll try to get used to that variant again. Let’s see how good that works.

As always I’m highly interested in feedback of any kind. Tell me what you like but especially also what you didn’t like. I can only get better when I know where to improve. Don’t hesitate to mention even spelling mistakes or the like. I’m happy to hear about everything I can do better.

Update (24th November): Maybe I should share my impressions of the talk. I like giving talks and giving this one in English via a web stream was a quite interesting experience. The English talks I gave until now where about half an hour, so this one lasting 55 minutes (+discussion) was quite a bit longer. Nevertheless it proved to be not much of a difference. As far as I remember I haven’t been looking for words, etc. So I’m quite satisfied with the language although German is still a bit more comfortable for me.

Due to some technical problems, I had to interrupt my talk to wait for a part of the audience rejoining. This made me hurry up a bit to keep the time frame. I tried to do this in those parts of the talk the audience most likely was already familiar with. But I’m afraid I was a bit fast anyway.

Web streaming the talk in my eyes had two effects: a positive one and a negative one. The negative one is that I could not see the audience and thus could not react to whether they looked bored or confused or rejecting or whatever. Normally a good presenter should keep an eye on how the audience reacts. Here I didn’t have the opportunity to do so. The second effect I believe to have encountered was that not seeing the audience made me avoid saying “erm“. Normally I use this “erm” a lot (and I try to stop that). During the talk I found myself rather making an actual pause or speaking slower instead. This is good. My guess is that not seeing the audience makes me less feel the need to make this sound as it normally just works as a signal which says “Don’t interrupt me, I haven’t finished talking yet.” But maybe I also just have a wrong impression. I didn’t concentrate on this aspect as language was more important.

At the end there was the opportunity for discussion but there was only one question. Unfortunately in my eyes I didn’t answer this question well. It was actually pretty bad. So after the break I tried to give a better answer.

Like so often, feedback is scarce. It’s a pity. I’d love to hear some comments on my presentation style, my English, the topic, etc. Even negative comments. The above is just my impression and maybe it’s wrong. Most likely there are also aspects I don’t realise, so feedback is always good if you want to improve.

Fehlerbehandlung in mehrschichtigen Systemen

… oder kurz: Schichten und Exceptions

Die Delphi-Tage 2012 sind zu Ende. Wie üblich hab ich nen Vortrag gehalten. Diesmal gings um Schichten, um Exceptions und was das eine mit dem anderen zu tun hat.

Abstract:
Wie strukturiert man eigentlich Software? Braucht Software überhaupt eine Struktur? Und, wenn ja, wie kann die aussehen? Und wie behandelt man eigentlich Fehler und Ausnahmesituationen? Sind Exceptions hier das Maß aller Dinge? Wie setzt man sie richtig ein? Und was hat das Ganze mit Schichten zu tun? Dieser Vortrag gliedert sich in zwei Teile. Im ersten Teil wird gezeigt, wie man Software in Schichten strukturieren kann und welche Vorteile das hat. Außerdem werden ein paar Buzzwords wie “Architektur”, “Layers” und “n-Tier” geklärt. Der zweite Teil befasst sich mit Exceptions, wie man diese richtig einsetzt und was das Ganze mit Schichten zu tun hat.

Resümee:
Ich halte gerne Vorträge und noch lieber halte ich sie, wenn interessiertes Publikum vorhanden ist. Und das war es. Und es hat Spaß gemacht. Der Raum war voll und das obwohl die parallel stattfindenden Vorträge sich eigentlich auch sehr interessant angehört haben. Was mich besonders gefreut hat, war, dass es viele gute Fragen gab. Es ist immer schön zu sehen, wenn man mit dem Thema etwas getroffen hat, das nicht nur einen selbst interessiert.

Von meiner Seite aus muss ich sagen, dass eigentlich alles ziemlich gut geklappt hat. An Details kann man natürlich immer feilen. Deshalb mal wieder die Bitte um Feedback. Diverse positive Rückmeldungen hab ich schon bekommen (was mich sehr gefreut hat). Da ich mich aber nur verbessern kann, wenn ich weiß, was nicht so gut war, bitte ich auch und insbesondere um negatives Feedback. Was war nicht den Erwartungen entsprechend, was war verbesserungswürdig, unnötig oder unverständlich? Was hat gefehlt?

Folien und Vortragsnotizen:
Ich habe diesmal getrennte Folien und Vortragsnotizen. Auf den Folien steht nicht sonderlich viel drauf, was sie für den Vortrag passender gemacht hat (denke ich zumindest). Dafür gibts zusätzliche Vortragsnotizen. Diese sind demgegenüber ausführlicher und enthalten teilweise sogar ganze Textabsätze. Das ist jetzt nicht so detailliert und ausgefeilt wie ein Tutorial, aber es sollte ausreichen, um auch verständlich zu sein, ohne dass man den Vortrag gehört hat. Feedback hierzu ist natürlich auch willkommen. Also hier die Downloads:
Download: Schichten und Exceptions: Folien (Größe: 2.99 MB; bisher 149 mal heruntergeladen)
Download: Schichten und Exceptions: Vortragsnotizen (Größe: 3.05 MB; bisher 168 mal heruntergeladen)

Hinweise:

  • Danke für den Hinweis, dass in den Folien ein “Create” gefehlt hat. Ist jetzt korrigiert.
  • Nach dem Vortrag würde ich noch auf EurekaLog als Alternative zu madExcept hingewiesen. Der Hinweis findet sich nun auch in den Vortragsnotizen.
  • Ebenfalls vielen Dank für den Hinweis, dass man die UML-Packages, die erstmal ja nur eine logische Gruppierung darstellen, mit Delphi-Packages umsetzen kann. Der eigentlich passende Mechanismus wären IMHO wohl Namespaces, die es in Delphi in der Form nicht gibt. Und wenn man sich .NET und Java ansieht, wird man feststellen, dass es dort beides gibt: Namespaces/Java-Packages und Assemblies/jar-Dateien. Beides, logische und physische Gruppierung, ist orthogonal, d.h. vollkommen unabhängig voneinander. So kann eine Assembly mehrere Namespaces enthalten und umgekehrt. Dabei ist die physische Gruppierung die eindeutig schwergewichtigere. Trotzdem halte ich das für einen wertvollen Hinweis. Man sollte sich durchaus überlegen, ob Delphi-Packages nicht doch in Frage kommen, um einzelne Schichten/Packages voneinander zu entkoppeln. Ist wohl eindeutig eine Überlegung wert.
  • Die Graphik mit dem schlecht wartbaren Subsystem wurde mit einer Software des Fraunhofer IESE erstellt. Links dazu sind in den Vortragsnotizen.
  • Zwei “Problembereiche” von Exceptions wurden noch angesprochen: DLLs und Threads. Ich hab nochmal nachgeguckt, aber leider hab ich keine Links dazu parat. Und ein Patentrezept hab ich leider auch nicht. Von daher kann ich wohl nur wiederholen, was ich schon als Antwort gegeben hatte: Exceptions an DLL- und Threadgrenzen vermeiden (noch mehr als sonst) und ggf. auf die anderen Fehlerbehandlungsmechanismen ausweichen (Fehlercodes, OnError-Events, etc.). Man könnte sich auch andere Ausweichstrategien überlegen. Beispielsweise Records mit den Fehlermeldungen zurückgeben, Window-Messages verschicken, etc. Auch kann man sich um ne DLL auf der Aufruferseite wieder einen Wrapper schreiben, der Fehlercodes, die als Ausweichstrategie verwendet wurden, wieder in Exceptions umschreibt. Leider gibt es wohl keine perfekte Lösung. Was im konkreten Fall nun vorzuziehen ist, hängt dabei wohl auch stark von den jeweiligen Rahmenbedingungen und Anforderungen ab.
  • Testgetriebene Entwicklung/Test-First-Ansätze wurden erwähnt. Genau genommen unterscheide ich zwischen den beiden Begriffen (was nicht alle tun). Vielleicht mach ich dazu mal nen separaten Blog-Post darüber. Vereinfacht gesagt geht es darum, den Test-Code zuerst zu schreiben. Und das hat dann Auswirkungen auf das Design. Eigentlich geht es noch um viel mehr. Weil ich das aber hier nicht alles erwähnen kann, verweise ich lieber auf Wikipedia, die einschlägigen Blogs und diverse Bücher zum Thema.
  • Zu Assertions hab ich letztes Jahr schon ein bisschen was gesagt. Außerdem kann ich auf das auch anderweitig unbedingt zu empfehlende Buch “The Pragmatic Programmer” verweisen. Da gibts auch ein kleines bisschen etwas dazu. Im übrigen sind Andrew Hunt und David Thomas auch meiner Meinung, dass man Assertions nicht unbedingt deaktivieren muss.
  • Design by Contract wurde auch kurz erwähnt. Hier ein passender Link dazu.
  • Ich hoffe, ich hab hier nichts vergessen. Vielen Dank jedenfalls auch für die anderen Kommentare.

Nachtrag:
Eine Möglichkeit zur Verbesserung ist mir gerade selbst noch eingefallen: Mit einem Laserpointer würde sich wohl deutlich besser auf die Leinwand zeigen können als mit der Hand. Ich glaub, ich sollte mir für nächstes Jahr so ein Ding zulegen. Ansonsten würde ich gerne wissen, ob ich verständlich war. Sowohl inhaltlich alsauch sprachlich. War ich zu schnell, zu langsam, zu laut, zu leise? Wie war meine Körperhaltung und keine Ahnung was… Ich bitte auch um Kritik an Kleinkram.

Wollt ich nur mal gesagt haben…

  • Redundanzen sind doof.
  • Variablen, die eigentlich lokal deklariert sein könnten, aber als Attribut in der Klasse stehen, sind eklig.
  • Variablen, die als String deklariert werden, obwohl sie Integers, enums oder gar Objekte sein könnten, sind scheußlich.
  • Objekte, die erzeugt, aber nicht verwendet werden, sind sinnfrei.
  • Magic Values sind böse.
  • Konstanten sind nicht böse. Man darf sie ruhig verwenden.
  • Bezeichner, die nicht das kommunizieren, was sie bezeichnen, sind nervig.
  • Bezeichner, die absolut gar nichts aussagen, sind <hier stark negativ besetztes Adjektiv einsetzen>
  • Lange Parameterlisten sind schwer lesbar und zeugen von schlechtem Design.
  • Wenn ich bei Methoden Parameter abzählen muss, um zu gucken, ob ich einen vertauscht hab, ist da etwas faul.
  • Wenn ich Parameter mit Dummy-Werten füllen muss, läuft da was schief.
  • Magic Values sind böse.
  • Objektorientiert programmiert man nicht, wenn man irgendwie Objekte verwendet, sondern, indem man objektorientiert denkt.
  • Objekte sind etwas anderes als Tabellen. Ja, wirklich.
  • if (a == null) return null; else return a; ist das selbe wie return a;
  • REST ist jetzt nicht furchtbar kompliziert. Aber den Unterschied zwischen Ressourcen und Verben sollte man schon verstanden haben.
  • Passwörter speichert man nicht im Klartext.
  • SQL Injection kann man verhindern
  • Magic Values sind böse.
  • Eine Klasse mit über 800 LOC ist vermutlich eher weniger “simple”.
  • NullPointerExceptions sollte man nicht fangen, sondern verhindern.
  • Obsoleten Code kann man entfernen. Man benutzt dazu wahlweise [DEL] oder [Backspace].
  • Code einheitlich einzurücken, tut nicht weh. Zumal einem die IDE dabei helfen kann.
  • Fehlerbehandlung heißt nicht, im Fehlerfall nen Stacktrace auszugeben und dann einfach weiter zu machen, als wär nichts gewesen.
  • Hab ich schon erwähnt, dass Magic Values böse sind?
  • Meine Zehnägel tun weh.

Wollt ich nur mal loswerden…

Enbugging — Wie wir Fehler machen und wie wir sie vermeiden

Wie im letzten Jahr, hab ich auch dieses Mal wieder einen Vortrag auf den Delphi-Tagen gehalten. Diesmal gings ums Fehler vermeiden. Man könnte auch sagen, um konstruktive QA-Maßnahmen. Egal. Jedenfalls gings um Bugs.

Abstract

“Wenn Debugging der Vorgang ist, Fehler aus einem Programm zu entfernen, dann ist Programmierung der Vorgang, Fehler in ein Programm einzubauen.” So liest man zuweilen im Netz und manchmal ist es nur zu wahr. Stunden verbringen wir damit, umständlich einen Fehler zu suchen, den wir zuvor noch ganz mühelos einbauen konnten. Wäre es da nicht praktischer, statt uns mit Debugging aufzuhalten, das Enbugging, das Einfügen von Fehlern gar nicht erst zu betreiben? Letztendlich sind wir ja eigentlich selbst schuld: Bugs entstehen nicht aus dem Nichts. Vielmehr erzeugen wir — meist unabsichtlich — Bedingungen, unter denen diese kleinen Krabbelviecher so prächtig gedeihen. Dieser Vortrag soll zeigen, wie Bugs entstehen und was wir dagegen tun können. Eine vollständige Betrachtung des Themas kann dabei natürlich nicht erfolgen. Stattdessen wird ein Überblick gegeben, um danach einzelne Aspekte zu vertiefen.

Folien

Wie versprochen gibts hier die Vortragsfolien: Download: Enbugging (Größe: 1.14 MB; bisher 355 mal heruntergeladen)

Ich hab wieder eine Gratwanderung zwischen vortragsunterstützenden Folien und Infos für alle, die den Vortrag nicht gesehen haben, versucht. Ob mir das gelungen ist, darf jeder selbst beurteilen (und mir am besten auch noch ein bisschen Feedback geben).

Hinweise

  • Eigentlich wollte ich noch erwähnen, dass Tony Hoare (der übrigens auch den QuickSort erfunden hat) auch dran schuld ist, dass in Pascal die geschweiften Klammern Kommentare sind. Hoare hat Vorbedingungen und Nachbedingungen in geschweiften Klammern vor bzw. hinter Code geschrieben (“Hoare-Tripel“) und damit formale Verifikation gemacht. Niklaus Wirth gefiel das Ganze so gut, dass er die geschweiften Klammern zu Kommentarzeichen machte.
  • Um die Beispiele zu verstehen, sollte man sich genau angucken, wie die Bezeichner (insbesondere die Klassen) heißen. Man sollte daraus erraten können, worum es geht. Meine Beispiele waren meist allgemein bekannte Datenstrukturen (List, Map, Set) oder standen in losem Zusammenhang mit Feedreadern, HTML-Parsern u.ä.
  • “Meine Fehlerliste” enthält viel zu wenige Daten, um hieraus schon etwas Sinnvolles ableiten zu können. Da muss ich noch mehr sammeln. Das hab ich beim Vortrag zwar schon dazu gesagt, aber es steht so explizit nicht in den Folien.
  • Was ich auch im Vortrag erwähnt hab, aber nicht auf den Folien steht: Bidirektionale Assoziationen sind starke Kopplungen. Also wenn sich zwei Module gegenseitig kennen, anstatt dass nur ein Modul das andere kennt, aber nicht umgekehrt. Man sollte deshalb zusehen, dass man möglichst nur einseitige Beziehungen hat.
  • Der Anhang enthält noch weitere Beispiele und Hinweise auf weiterführende Themen, die nicht angesprochen werden konnten.

Errata

  • Auf Folie 60 fehlt ein not. Es müsste also heißen if not FInnerList.Contains(item) then.

Bitte um Feedback

Das Feedback, das ich bisher bekommen hab, war durchweg positiv. Das freut mich. Ich will hier aber trotzdem nochmal nach Feedback und explizit auch Kritik fragen. Nur, wenn ich weiß, was ich besser machen kann, kann ich in Zukunft etwas weniger schlimme Vorträge machen… *g*

Insbesondere würde mich folgendes interessieren:

  • Hab ich verständlich geredet? War ich vielleicht zu schnell?
  • Waren die Beispiele verständlich? Nachvollziehbar? Praxistauglich?
  • Wie versteht man die Folien, wenn man sich den Vortrag nicht angehört hat?
  • Waren Thema und Inhalt angemessen? Zu theoretisch? Zu einfach? Zu schwer? Zu trivial?
  • Kann ich sonst etwas verbessern?

Eiffel: Das Esperanto unter den Programmiersprachen

Ich gehöre zu denjenigen, die sich gerne immer mal wieder eine neue Programmiersprache ansehen. Nicht um in jeder dieser Programmiersprachen letztendlich auch produktiv zu arbeiten, aber um mal “übern Tellerrand zu gucken”.

Das Ganze ist nicht nur interessant, sondern hat auch den Vorteil, dass man sehr viel über unterschiedliche Herangehensweisen und Programmierkulturen erfährt. Die einzelnen Sprachen unterscheiden sich nicht nur in der Syntax, sondern auch in der Denkweise, wie Probleme gelöst bzw. Code geschrieben wird. Sowas ist manchmal augenöffnend und kann auch mal helfen, kreative Lösungen für schwierige Probleme zu finden, die man in “seiner” Programmiersprache hat.

Das heißt natürlich nicht, dass man anfangen sollte, die eigene Sprachkur zu missachten. Im Gegenteil: Manchmal ist es sinnvoller, eine schlechte, aber allseits bekannte Lösung zu verwenden, als eine elegante, die für andere Entwickler “fremdartig” wirkt. Code schreibt man i.d.R. ja nicht nur für sich selbst, sondern auch für die anderen Entwickler im Team, etc.

Aber für schwierige, nicht-alltägliche Probleme kann man auch mal eine kreative Lösung gebrauchen. Und dafür ist es ganz gut, wenn man mit anderen Sprachen und Programmierkulturen in Kontakt kommt. Außerdem ist es mit Programmiersprachkulturen ähnlich wie mit natürlichen Sprachen: Sie verändern und beeinflussen sich gegenseitig und das ist eine Bereicherung. [1]

Ich bin nicht der einzige, der so denkt. In “The Pragmatic Programmer” [2] geben Andy Hunt und Dave Thomas den Rat: “Learn at least one new language every year.” Und da komm ich sogar in etwa hin. Die meisten davon kann ich nicht (mehr) wirklich gut. Wirklich produktiv einsetzen kann ich momentan davon nur ne Hand voll. Aber darum gehts ja auch nicht.

Nun, ich hab mich jetzt ein bisschen mit Eiffel beschäftigt. Aus Zeitgründen leider nur oberflächlich. So hab ich praktisch keinen echten Code geschrieben sondern nur Tutorials und Code gelesen. Das bedeutet natürlich, dass viel von der Syntax bald wieder verflogen sein wird. Aber wie gesagt: Darum gehts mir gar nicht.

Ich hab also einen Eindruck von Eiffel bekommen. Um jetzt mehr als ein Bauchgefühl vermitteln zu können, müsste ich wohl wirklich mal ein paar hundert Zeilen Code schreiben. Aber dafür hab ich momentan keine Zeit. Hier also nur mal ein erster Eindruck. weiter lesen »

checkLectures

Wenn man studiert, hat man üblicherweise Lehrveranstaltungen. Und zumindest in der Informatik ist es auch üblich, da wirklich hinzugehen [1]. Und es ist üblich, dass es die Folien zum Download gibt. Dann kann man sich die ausdrucken und während der Vorlesung Notizen drauf machen.

Normalerweise gibt es also zu jeder Vorlesung eine Webseite mit den ganzen Materialen (Vorlesungsfoien, Übungsblätter) und ein paar News. Da man natürlich wissen will, wann es neue Folien gibt oder neue Übungsblätter oder wenn, sagen wir mal, der Raum verlegt wird, ist es wichtig, dass man ständig die Vorlesungsseite besucht. Das Ganze macht man mindestens einmal täglich, wenn nicht öfter.

Wie schön wäre es da, wenn alle Vorlesungsseiten einfach einen Newsfeed anbieten würden. Dann würde der Feedreader die ganze Arbeit machen und man müsste nicht ständig selber gucken, sondern nur, wenns wirklich was Neues gibt. Leider ist das die große Ausnahme. Nur ein Bruchteil der Vorlesungsseiten hat einen Feed. Schade.

Gestern hatte ich dann mal wieder so einen Warum-ist-mir-das-nicht-schon-früher-eingefallen-Erlebnis. Ich könnte mir doch schnell ein kleines Skript zusammenbasteln, das mir die Arbeit abnimmt. Für was bin ich denn eigentlich Informatiker, wenn ich schon so Kleinkram nicht automatisiere! Warum muss mir sowas eigentlich erst im 9. Semester einfallen?

Ich hab mich also kurz mal hingesetzt und ein kleines Ruby-Skript geschrieben. Es ist nicht furchtbar schön, aber es tut seinen Zweck:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#!/usr/bin/ruby

require 'pathname'

# configuration
$path = File.dirname(Pathname.new(__FILE__).realpath)
$lecturesFile = $path + '/lectures.list'
$browser = 'opera'

def checkLecturesInFile(lecturesFile)
        items = File.open(lecturesFile).readlines
        File.open lecturesFile, 'w' do | file |
                items.each do | item |
                        data = item.split ';'
                        name = data[0].strip
                        url = data[1].strip
                        hash = data[2].strip

                        newHash = `wget "#{url}" -qO - | md5sum | cut -d " " -f 1`
                        newHash.strip!
                        if hash == newHash
                                puts "#{name}: OK"
                        else
                                puts "#{name}: new"
                               `#{$browser} "#{url}"`
                        end
                        file.puts "#{name} ; #{url} ; #{newHash}"
                end
        end
end

# main
checkLecturesInFile $lecturesFile

[2]

In der Datei lectures.list ist dann ne URL-Liste in folgendem Format:

1
<Name> ; <URL> ; <md5Hash>

also z.B.

1
CRDE ; http://www.christian-rehn.de ; b1306d712bc39ecfb95fa8d29c8d23a4

Das Skript geht die Datei Zeile für Zeile durch, ruft die Webseite ab, berechnet einen Hash-Wert und vergleicht ihn mit dem gespeicherten Hash. Hat sich die Seite geändert wird sie automatisch im Browser geladen. Der neue Hash wird dann wieder in die Datei gespeichert. Die Idee ist einfach und funktioniert in den meisten Fällen. Leider eben nicht in allen:

  • Manche Vorlesungsseiten sind passwortgeschützt. HTTP Auth ist per wget kein Problem, aber wenn wenn handgestrickte Lösungen ins Spiel kommen, müsste man das genau auf die jeweilige Seite anpassen. Einfach nen Cookie zu übergeben klappt i.d.R. nicht, da wohl weitere Header überprüft werden (um Session Hijacking zu vermeiden). Das also jeweils anzupassen ist mehr Arbeit, die sich nicht unbedingt lohnt.
  • Manche Vorlesungsseiten generieren Session IDs oder ähnliche Tokens und bauen sie in die Links mit ein. Das ändert natürlich den Hash, womit der Ansatz nicht mehr klappt. Ich hab auch schon überlegt nen HEAD-Request mit If-Modified-Since zu senden, aber die meisten dynamischen Seiten machen sich hier keine große Mühe und geben immer Modified zurück, womit der Ansatz schon generell ausscheidet.

Nicht perfekt, aber das muss es auch nicht. Auf jeden Fall besser als alles immer händisch prüfen.

[1] Das lohnt sich auch, denn die Vorlesungen sind meistens gut.
[2] Der Code ist trivial und darf von jedem ohne Einschränkung verwendet werden.


Update(30.08.11): kleiner Bugfix

Dynamische Bindung

Zu dem, was in der OOP oft als sehr kompliziert wahrgenommen wird, gehört wohl eindeutig die dynamische Bindung. Hier mal eine kurze Erläuterung dazu:

Statischer und dynamischer Typ

Um dynamische Bindung zu verstehen, ist es zuerst einmal notwendig, zwischen statischem und dynamischem Typ zu unterscheiden. Bei der Typisierung geht es immer um den Typ, der einer Variablen zugewiesen wird. Jede Variable hat einen Typ, der angibt, was die Variable beinhalten bzw. referenzieren kann.

Wird eine Variable vom Typ Foo deklariert, kann sie alle Objekte vom Typ Foo referenzieren. Dazu gehören aber auch alle Objekte von Subtypen. Ein Objekt eines Subtyps ist gleichzeitig auch immer Objekt aller Supertypen (Subtyppolymorphie). Beispiel:
weiter lesen »

SE1: Parsing-Grundlagen

Ich hatte vor einiger Zeit versprochen, noch etwas über Parsing zu schreiben bzw. über die prinzipielle Herangehensweise an Parsing-Probleme. Ich bin da selbst kein Experte und hab die zugehörige Vorlesung zum Compilerbau auch noch nicht gehört. Allein schon aus diesem Grund werde ich nicht sehr ins Detail gehen, sondern möglichst einfach einen Überblick geben. Wer mehr wissen möchte, sollte sich in die passende Vorlesung setzen und/oder ein einschlägiges Buch lesen.

Parsing bzw. Compilerbau ist ein sehr gut erforschtes Gebiet der Informatik. Damit beschäftigt man sich schon seit Ewigkeiten. Dementsprechend gibt es da sehr viel Kompliziertes, Detailliertes und auch Nützliches. Der klassische Compilerbau hat sich dabei auf verschiedene Klassifikationen von Grammatiken gestürzt und in der Tat ist das ein Ansatz, der oft sehr hilfreich, weil sehr systematisch ist. In der Praxis will man aber nicht immer einen Compiler schreiben (oder ähnlich komplexe Aufgaben lösen) und so gibt es in der Praxis noch ein paar andere Ansätze, die teilweise ihre Wurzeln zwar ebenfalls im Compilerbau haben, aber dennoch anders funktionieren. Im Folgenden werde ich über alles, was mir so an Ansätzen einfällt, einen Überblick geben und die prinzipielle Herangehensweise erläutern. weiter lesen »

SE1: FizzBuzz

Wöchentlich stelle ich “meinen” SE1-Studenten ein paar kleine meist sehr einfache Aufgaben. Letztens hab ich ihnen versprochen, die Aufgabe zu “Java” wird ein Kinderspiel. Und genau das war sie auch:

Das Spiel geht folgendermaßen: Es geht reihum und dabei muss gezählt werden. Jeder sagt die Zahl, die um eins höher ist, als die vorherige. Es wird bei 1 angefangen und der, der einen Fehler macht, scheidet aus dem Spiel aus. Damit das nicht so einfach ist, werden alle Vielfache von 3 durch “Fizz” und alle Vielfache von 5 durch “Buzz” ersetzt. Vielfache von 3 und 5 werden durch “Fizzbuzz” ersetzt. Damit ergibt sich folgende Folge:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuzz
16
...

Ich hätte jetzt gerne eine Prozedur, die einen int-Parameter entgegen nimmt und das Ganze bis zu dieser Grenze durchexerziert. Also fizzbuzz(16) gibt genau die obige Ausgabe auf der Konsole aus.

Die Aufgabe selbst ist nicht weiter spannend, eigentlich sogar ziemlich langweilig. Etwas weniger langweilig ist aber, wo ich die Idee her hab. weiter lesen »

Magic Values

Letzte Woche hab ich ja schon etwas über Code Smells geschrieben. Einen weit verbreiteten Code Smell, nämlich die Magic Values, habe ich letztens mal wieder angetroffen und so nehme ich das mal zum Anlass, darüber etwas zu schreiben.

Der Begriff “Magic Value” oder “Magic Number” hat mehrere Bedeutungen. Hier geht es um den Code Smell der Magic Values, also insbesondere nicht um besondere Werte (d.h. Bytefolgen) als Erkennungszeichen in Dateiheadern o.ä.

Es geht also um Code, den man häufig vorfindet, der aber verbesserungswürdig ist. Hierzu sehen wir uns ein paar Beispiele an und werden unterschiedliche Arten von Magic Values ausmachen können:

Magic Values 1. Art: Unveränderliche Werte

1
... days * 1440 ...

Warum nun days mit 1440 multipliziert wird, wird aus dem Code nicht klar.

Besser:

1
2
3
4
5
6
7
// mit einer Funktion ist es klarer
function daysToMinutes(ADays: Integer): Integer;
begin
  return ADays * 1440;
end function;

... daysToMinutes(days) ...

Aber auch das geht besser:
weiter lesen »

powered by WordPress | QuickLaTeX | WordPress Themes