Terminplaner in Ruby

June 3, 2009 at 7:20 pm 4 comments


Ich habe den Terminplaner, den ich bereits in Java, Groovy und Common-Lisp programmiert habe, auch mal in Ruby programmiert. Die Line-of-Code habe ich für den Vergleich mal etwas professioneller ausgewertet. Hier das Ergebnis:

Sprache Anzahl Dateien Line of Code (ohne Kommentare)
Java 7 296
Groovy 7 230
Ruby 7 236
Common-Lisp 6 140

Die Ursachen dafür, dass die Lisp-Lösung so wenig Zeilen hat, habe ich hier bereits früher erklärt.

Die Lösungen in Groovy und Ruby sind erwartungsgemäß ungefähr gleich lang. Neben der Länge fallen aber noch viel mehr Ähnlichkeiten auf.

Folgender Code steht im Groovy-Beispiel:

public Collection getTermine(String besitzer, boolean zeigeAuchAbgelehnte) {
	return termine.inject([]) {result, termin ->
		termin.fuegeZuTerminlisteHinzu(result, besitzer, zeigeAuchAbgelehnte)
		result
	}
}

Im Ruby-Beispiel finden wir den entsprechenden Code:

def termine(besitzer, zeige_auch_abgelehnte)

	@termine.inject([]) { |result, termin|

		termin.fuege_zu_terminliste_hinzu(result, besitzer, zeige_auch_abgelehnte)
		result

	}.sort

end

Natürlich ist die Syntax unterschiedlich, aber diese Unterschiede halten sich durchaus in Grenzen. Die Syntax für Closures ist beispielsweise fast identisch und das API der Collections ebenfalls. Auf jeden Fall finde ich, dass Groovy und Ruby größere Ähnlichkeiten aufweisen als Groovy und Java – jedenfalls, wenn man in Groovy auch mit Groovy-Style programmiert.

Diese Medaille hat zwei Seiten: Der Umstieg von Java auf Groovy ist fast so schwer wie von Java auf Ruby. Wenn man allerdings Groovy oder Ruby beherrscht, ist der Umstieg auf die jeweils andere Sprache relativ einfach.

Den vollständigen Quellcode zum Beispiel kann man sich bei github herunterladen.

Entry filed under: 1. Tags: .

Stop the Line in der Softwareentwicklung Das Internet und die Freiheit

4 Comments Add your own

  • 1. marko  |  June 8, 2009 at 3:08 pm

    Warum ist die Methode nicht einfach so implementiert:

    @termine.find_all { |termin| termin.sichtbar?(besitzer, auch_abgelehnte) }

    (mit natürlich einer leicht abgewandelten Methode “sichtbar?” in der Klasse Termin, anstatt “fuege_zu_terminliste_hinzu”)

    Im Quelltext sehe ich dort den Kommentar “TDA: Tell, don’t ask”. Aber wozu hier TDA?

    TDA finde ich in Situationen sinnvoll, wo man ein Objekt zuerst etwas fragt, um es dann ggf. zu verändern. Aber hier wird der Termin ja gar nicht verändert. Löst TDA hier also kein Problem, sondern macht den Code nur unverständlicher? Testbar sind auch beide Varianten.

  • 2. stefanroock  |  June 8, 2009 at 4:51 pm

    Dein Vorschlag macht den Code 5 Zeilen kürzer und eliminiert ein IF-Konstrukt. Das ist auf jeden Fall gut.

    Für Groovy gilt dasselbe. Dort würde sich derselbe Umbau anbieten.

    Und jetzt zur Frage, warum ich das da eingebaut habe. Der Ursprungscode ist bereits ein paar Jahre alt und entstand unter Java. Mit Sicherheit kann ich nur sagen, dass ich TDA damals für eine gute Idee gehalten habe🙂

    Unter Java lässt sich TDA vielleicht noch eher argumentieren, weil man das IF-Konstrukt ohnenin braucht. Ohne TDA wird der Code also nicht wirklich einfacher. Dafür kann man mit TDA das API von Termin etwas kleiner halten.

  • 3. marko  |  June 9, 2009 at 8:38 am

    Das ist natürlich eine Gefahr, wenn man ein Problem in mehreren (sich doch noch zu ähnlichen) Sprachen implementiert: Man neigt dazu, die Strukturen der ersten Implementierung in die späteren zu übernehmen.

    Und wenn man mit Ruby eigentlich Java programmiert, dann macht das den Vergleich der Implementierungen zwischen Ruby und Java schwierig. :-)

  • 4. stefanroock  |  June 9, 2009 at 8:44 am

    Klar. In der ersten Groovy-Version der Java-Lösung habe ich auch zuwenig Gebrauch gemacht von den Features der Groovy-Collection-Library.

    Außerdem glaube ich, dass die Verwendung der BenutzerNichtEingeladenException in Java OK ist, in Groovy und Ruby aber zu unnötig kompliziertem Code führt.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Trackback this post  |  Subscribe to the comments via RSS Feed



%d bloggers like this: