Montag, 18. Juli 2011

Aufbau des Frameworks in der Theorie, Teil 1 - Controller

Die Controller sind das Bindeglied zwischen den Views und dem Model. Darum wird dieser Teil der wahrscheinlich meistgenutzte sein.
Die Grundidee des Controllers in einem Webframework ist das Binden eines Callbacks an eine Route und die Benennung dieser Routen auf Basis von Konventionen, basierend auf den Entitäten, die im Model definiert werden. Dabei arbeiten wir in einer REST-Architektur, so dass sich allein durch den Namen des Models schon alle Actions als Routen ableiten lassen.
Klingt kompliziert, ist es aber gar nicht. Nehmen wir im einfachsten Fall an, wir erstellen ein Model namens Post, welche die Properties "title" und "body" erhält.
Der Controller zu diesem Modell würde dann also der posts-controller sein und standardmäßig Actions für das Erstellen, Bearbeiten, Anzeigen und Auflisten von Posts zur Verfügung stellen.
Da wir nach dem REST-Prinzip arbeiten, wissen wir schon wie Routen auszusehen hätten, nämlich:

  • Auflisten: GET /posts
  • Anzeigen von post mit der id 1: GET /posts/1
  • Erstellformular: GET /posts/new
  • Erstellen: POST /posts
  • Bearbeiten-form für post 1: GET /posts/1/edit
  • Änderung an post 1 speichern: PUT /posts/1
  • Löschen-Seite für post 1: GET /posts/1/delete
  • Löschen von post 1: DELETE /posts/1

Ich habe mich dazu entschieden den Ruby-Webserver Thin zur Auslieferung zu nutzen, der alle Http-Methoden der Rest-Architektur voll unterstützt und voll kompatibel zur Rack, einem Ruby-Interface zu Webservern, ist.

Nun müsste man nur noch auf Basis von Rack ein Framework erstellen, dass die Handler für die Methoden bequem aufrufen und an Callbacks hängen lässt, welche die benötigte Template-Engine zum Rendering beherscht.
Das haben sich andere schlaue Köpfe bereits überlegt, in Code umgesetzt und das ganze Sinatra genannt. Sinatra stellt ein Microframework in Form einer Domänen-spezifischen Sprace zur Verfügung. Ich werd hier nicht tiefer auf die Funktionsweise und irgendwelche "Hello-Worlds" eingehen, da die ReadMe von Sinatra, die für Englisch-Muffel auch ins Deutsche übersetzt wurde, das bereits ganz hervorragend erledigt.
Wie wir in zukünftigen Posts sicher noch sehen werden, ist Sinatra wunderbar zu erweitern, was dem erstrebten DRY-Prinzip sehr entgegenkommt.
So wundert es nicht, dass ich mit Sinatra-Resources bereits eine Erweiterung ausgemacht hab, mit dem sich das Resourcen-basierte Prinzip der MVC-Arbeitsweise hervorragend umsetzen lässt.

Was der Abtrennung der einzelnen Controller voneinander bekömmlich ist, ist die Möglichkeit der Modularisierung in Sinatra. Damit können wir Klassen schreiben, die sich von Sinatra::Base ableiten und haben damit die Möglichkeit Controller tatsächlich auf Basis ihres zu Grunde liegenden Models zu benennen und in eigene Dateien zu stecken.

Ein weiterer Aspekt der Sinatra zur Auswahl verhalf ist die Unterstützung aller möglichen und unmöglichen Rendering-Engines, die im Webberreich vorhanden sind, welche sich wiederum relativ einfach erweitern lässt. Da ich als Template-Engines Haml und Sass für HTML und CSS und eventuell Coffeescript für Javascript einsetzen werde, ist eine Erweiterung aber eigentlich nicht notwendig.

Damit sind wir auch schon bei den Views, zu denen nicht allzuviel zu sagen ist. Die Views stellen das Interface zwischen User und Controller dar und werden im Webbereich eben von HTML, CSS und Javascript dargestellt.
Will man DRY arbeiten, macht es Sinn in allen drei Bereichen Renderengines einzusetzen. Im HTML-Bereich ist die Templateengine der Wahl dabei einfach HAML, da dieses das Dry-Prinzip sogar bis in den HTML-Bereich überträgt und aufgrund der Struktur und Funktionalität besser für das Templating geeignet ist als beispielsweise Markdown, welcher in der Textgestaltung ganz hervorragend ist.
SASS macht das gleiche sogar für CSS und kommt auch aus der gleichen Schmiede. Früher war es sogar im gleichem Rubygem integriert.

Bei den Überlegungen in Richtung Coffescript, einer kleinen Sprache, die nach Javascript kompiliert wird, geht es weniger um DRY als um die Erhöhung der Lesbarkeit des Javascript-Codes. Insbesondere wenn man, wie ich, im Team mit reinen Webdesignern und Projektleitern/Systemarchitekten arbeitet ist verständlicher Code von nicht unerheblicher Bedeutung.
Umso leichter Code zu lesen ist, desto einfacher wird es eben Nichtentwicklern klarzumachen, was man an bestimmten Stellen aus welchen Grund tut.

Zum Theorieteil wird es mindestens noch zwei Teile geben. Einer wird sich mit den Modellen an sich und dafür  geeigneten Libraries auseinander setzen. Beim Zweiten wird es sich um Unittesting, dessem Sinn und der dafür eingesetzten Library drehen.

Selbstverständlichen wird es auch praktische Teile geben. Genaugenommen werden diese mittelfristig sogar den Hauptteil des Blogs ausmachen. Den Code sagt oft mehr als Bilder und die sagen ja bekanntlich schon mehr 1000 Worte.

Montag, 11. Juli 2011

Ekenntnis einer Reise

So, ich bin wieder zurück vom Segelturn und bin immer noch total angetörnt von dem Erleben des Ganzen. Ich konnte wirklich unglaublich viel an Eindrücken und Inspirationen sammeln und freu mich darauf so frisch gepowert neues schaffen.
Ohne allzu esotherisch wirken zu wollen, hab ich eine Sache mitgenommen: Alles wird gut. Das sag ich ganz automatisch um die zwanzig mal am Tag oder öfters. Der Streß der mir entgegenschlägt lässt sich sehr viel gelassener hinnehmen und ich geh in einer völlig neuen Rue durch den Tag.
Ich bin mir sicher, dass ich diese Einstellung in den "Arbeitsalltag" tragen kann und mein Leben als Webentwickler bereichern werde.
Wie das aussehen wird, könnt ihr sicher hier im Blog mitlesen. In diesem Sinne wünsch ich euch die Gelassenheit um locker durchs Leben zu gehen und hoffe ihr lest mich.

Samstag, 2. Juli 2011

Gedanken über Ruby

Die Welt spricht Ruby, egal wie oft sie dabei Rails sagt. Tatsache ist, dass Rails längst sicher nicht die Lösung aller Dinge der Rubywelt ist. Trotz allem darf man ihm seine Effizienz in der Entwicklungsarbeit nicht absprechen.

Und so wär es auf jeden Fall einen Blick darauf Wert, wie Rails diese Effizienz eigentlich erreicht und darüber nach zu denken, inwiefern man diese Erkenntnis in die Arbeit einfließen lassen kann.
Die Effizienz erreicht Rails zum einen durch die Verwendung des MVC-Entwufsmusters und die Einhaltung einiger wenigen strikter Prinzipien.

MVC-Entwurfsmuster


MVC steht für Model-View-Controller und ist ein seit langem bewährtes Muster der Softwareentwicklung, in dem es darum geht die Geschäftslokig von ihrer Präsentation zu trennen und eine Schnittstelle zwischen den beiden verfügbar zu machen.

Das Model ist dafür zuständig die Geschäftslogik festzuhalten und stellt somit quasi den Zustand des System dar. Es macht dabei nichts anderes, als mit Daten zu handeln. Es validiert und speichert die Daten um dann Methoden verfügbar zu machen, die Daten auch wieder abzufragen.
Die Modelle werden durch die Datenbankabstraktion zur Verfügung gestellt, wobei Object-Relationship-Mapping zum Einsatz kommt. Jedes Modell stellt eine Klasse dar und wird auf eine Tabelle der Datenbank gemappt.
Somit stellt jede Zeile der Datenbank ein Objekt dieser Klasse dar. Die Klasse stellt nun alle nötigen Getter-, Setter- und Valdierungsmethoden als Klassenmethoden zur Verfügung.

Der Controller ist ebenso eine Klasse, die als Schnittstelle zwischen dem Model und dessen Präsentation dienen soll. Zu jedem Modell steht ein eine Controllerklasse zur Verfügung, welcher die Klassenmethoden des Modell nutzt um Actions und Helper zu erstellen.
Eine Action wird immer dann ausgelöst, wenn der User in der Präsentationsschicht in irgendeiner Form mit den Modellen interagiert.
Hinter jedem dieser Action-Aufrufe steht ein Callback in dem alle Variablen für die Präsentation gesetzt, alle nötigen Methodenaufrufe für die Aktion gestartet und schließlich der Returnwert, meist in Form der Präsentation, an den User zurückgeliefert werden.

Die View steht dabei für die Präsentationsschicht. Sie stellt alle Möglichkeiten für den Anwender mit der Applikation zu kommunizieren dar.
Sie nutzt, die in ihrer Action gesetzten Variablen und die Helper, die der Controller zur Verfügung stellt, innerhalb einer Umgebung, welche die Darstellung übernimmt, also beispielsweise die Template-Engine.

Das DRY-Prinzip

DRY steht für 'Dont repeat yourself' und erklärt sich eigentlich schon fast von selbst. Man sollte jeden Sachverhalt genau einmal programmieren und diese Lösung dann als Resource im System zur Verfügung zur stellen. Die strenge Objektorientierung in Ruby stützt diesen Ansatz, stellen Klassen und ihre Instanzen gepaart mit den Methoden doch ein optimales Fundament dafür, wiederverwertbaren Code zu schreiben.
Bei dieser Idee geht es sehr viel weniger um Faulheit als um Übersicht und Wartbarkeit. Eine Sache die nur an einer Stelle programmiert wurde, muss bei Bedarf auch nur an einer Stelle geändert werden.

Konvention über Konfiguration


Wenn man sich darauf einigen würde, dass die Entwicklungsumgebung immer "Development" heißt und ferner noch dass die Datenbank zu einer Umgebung immer nach der Datenbank benannt wird, hätte man es schon geschafft eine Arbeitsumgebung zu schaffen in der jeder Teilnehmende zu jeder Zeit wissen sollte wo er eigentlich gerade ist.
Wenn darüber hinaus vereinbar würde, dass eine Datenbanktabelle als Namen immer die Pluralform des zugehörigen Models bekommt, würde man immer genau wissen woran man gerade arbeitet.
Gleichzeitig könnte man programmatisch eine Automation erschaffen, die einem genau diese Vorgänge, die immer die gleichen sind, abnimmt und hätte wieder Zeit für die Entwicklung der Applikation anstatt sich mit Konfigurationsdateien und ähnlichen Scheuslichkeiten auseinander zu setzen.

Wie sich diese Punkte mit welchen Werkzeugen umsetzen lassen, werde ich in den kommenden Wochen hier erörtern. Wir werden Sinatra, den Datamapper, Haml und Sass ebenso erforschen wie Rspec und die aufregende Welt des Test-Driven-Developments.
Ich freue mich schon auf diese spannende Reise. Aber zuerst freu ich mich auf sieben Tage Segelurlaub.