Exkurs: Smalltalk

Smalltalk war als eine einfache Sprache für den Programmieruntericht gedacht und zudem eine der ersten objekt-orientierten Computersprachen, lange bevor Objekt-Orientierung populär wurde.

Einige Smalltalk Fanatiker schimpfen gerne über Sprachen wie C++ oder Java und daß diese nicht wirklich objekt-orientiert seien, weil dort nicht alles object-orientiert ist. Ignorieren Sie gelassen dieses Geschrei einiger geistig unterbelichteter und lassen Sie sich den Spaß nicht verderben. Der Witz ist: In Smalltalk ist tatsächlich alles ein Objekt oder ein Teil davon:

Smalltalk Syntax

    * Kommentare sind in Gänsefüßchen: "Kommentar"
    * Punkte schließen eine Anweisung ab: a := a + 2.
    * Bei Methodenaufrufen mischen sich im Gegensatz zu C++/Java Methodenname und Parameter:
      Java/C++: win.set_x_y_width_height(5, 5, 120, 50);
      Smalltalk: win set_x: 5 y: 5: width: 120 height: 50.
      Dadurch lassen sich Aufrufe mit großer Parameteranzahl besser lesen.
    * Zuweisungen: a := 7.
    * Zeiger auf übergeordnete Klasse: super
    * Zeiger auf eigenes Objekt: self
    * Rückgabe von Werten am Ende eines Methodenaufrufs: ^ result.
    * '+' oder '*' sind Methoden von 'SmallInteger', darum gilt nicht die 'Punkt vor
      Strich-Rechnung' bei Ausdrücken:

      a := 7 + 1   * 2
           ^ ^ ^ ^ ^ ^
           | | | | | |
           | | | | | Parameter mit dem Wert 2
           | | | | Methode '*'
           | | | Der Aufruf '7 + 1' liefert ein Object vom Typ 'SmallInteger'
           | | | mit dem Wert 8
           | | Parameter vom Type 'SmallInteger' mit dem Wert 1
           | Methode '+'
           Objekt vom Typ 'SmallInteger' mit dem Wert 7

      Die Variable 'a' zeigt am Ende auf ein 'SmallInteger' Objekt mit dem Wert 16.
    * Es lassen sich auch Klammern setzen:
      a := ( 7 + 1 ) * 8 .
    * Anweisungsblöcke sind Objekte: [ a := a + 1. ]
    * Bedingungen sind Methoden der Klasse 'Boolean':

      v = 10               "Ein Vergleich liefert eine Klasse vom Typ 'Boolean' zurück."
        ifTrue:            "Die Methode 'ifTrue' der Klasse Boolean bekommt einen.."
        [                  "..Anweisungsblock als Parameter übergeben.."
          'Zehn' printNl.  "..der das Wort 'Zehn' auf den Bildschirm schreibt"
        ].

    * Schleifen sind Methoden von Anweisungsblöcken (kurz Block):

      v := 0.              "Setze die Variable v auf Null"
      [ v = 10 ]           "Ein Objekt vom Typ 'Block', das vergleicht ob v gleich 10 ist"
        whileFalse:        "Methode von Block, die den Block selbst und den als Parameter.."
        [ v printNl.       "..übergebenen Block solange ausführt, bis der erste Block.."
        v := v + 1. ].     "..wahr ist."

    * Auch Klassen sind Objekte und Ableiten ist ein Methodenaufruf:
            Object subClass: #MeinObject. 

Smalltalk ist aber gleichzeitig auch eine Programmierumgebung. Man schreibt nicht ein Programm, das man anschließend ausführt, sondern kann das Programm ändern, während es läuft.

Delegation

Für GUI Bibliotheken wurden eine Reihe von Mechanismen entworfen, damit Objekte miteinander kommunizieren können, ohne dabei aufwendig neu Klassen abzuleiten.

Hier einige Beispiele:

  • Callbacks (z.B. OSF/Motif, Gtk+)
  • Message Maps (z.B. Microsoft Foundation Classes)
  • Callback Objects (z.B. Fresco)
  • Signal & Slot (z.B. Qt, TOAD)
  • Anonyme Klassen (z.B. Java)

Mit dem in Smalltalk verfügbaren 'Block', auch 'Closure' genannt, waren solche Tricks jedoch nie nötig.Hier ein Beispiel mit GNU Smalltalk:

"*** create a TPushButton class ***"

Object subclass: #TPushButton
  instanceVariableNames: 'callback'
  classVariableNames: ''
  poolDictionaries: ''
  category: ''!

!TPushButton class methodsFor: 'various class methods'!
   
new
  | r |
  r := super new.
  ^r
! !

!TPushButton methodsFor: 'various instance methods'!

addCallback: aBlock
  callback := aBlock.
!
 
mouseDown
  callback value.
!
 
! ! 
    
"*** start the program ***"

Smalltalk at: #program put: (TPushButton new)!

program addCallback: [ 'button pressed' printNl. ].

program mouseDown!

Startet man das Programm, so wird der Aufruf der Methode mouseDown den Text „button pressed“ ausgeben.

Model-View-Controller (MVC)

Unter Smalltalk wurde auch die Model-View-Controller (MVC) Architektur zur GUI Programmierung eingeführt. Den Kern bilden 3 Klassen, die wie folgt zueinander in Beziehung stehen:



Model-View-Controller
  • Model
    Verwaltet die durch das Programm zu bearbeitenden Daten, z.B. Uhrzeit, Name einer Person.
  • View
    Verantwortlich für die graphische Ausgabe der im Model enthaltenen Daten. Z.B. die Darstellung der Uhrzeit als ein Kreis mit Zeigern.
  • Controller
    Nimmt Maus- und Tastaturereignisse entgegen und veranlaßt bei Bedarf, daß sich Modell und View ändern oder reichen die Ereignisse an andere Controller weiter.


Mehrfache Views bei MVC

Einem Model können mehrere Views zugeordnet sein. Z.B. kann ein Model, das eine Uhrzeit enthält ein View haben, das die Zeit als Kreis mit Zeigern und ein weiteres, das die Zeit mit Ziffern darstellt.
Ändert sich das Model, z.B. weil eine Minute vergangen ist, dann ändern sich auch die Views.



Beziehungen zwischen Views bei MVC

Views können weiterhin untergeordnete Views enthalten, was im Programm durch eine Baumstruktur von Views repräsentiert wird.



Pfad von Eingabeereignissen bei MVC

Eingaben werden von oben nach unten von den Controllern durch die von den Views vorgegebene Baumstruktur hindurchgereicht, bis sich ein Controller findet, der das Ereignis bearbeitet.

Eine abgspeckte Variante von MVC ist Model-View, wie es z.B. bei Java's Swing Bibliotheken Verwendung findet. Hier werden die Ereignisse nicht über Controller verteilt, sondern gleich über das zugrunde liegende Fenstersystem.

Objekt Orientierung, Delegation, Model-View-Controller, Smalltalk brachte all dies schon mit sich.

Der führende Kopf hinter der Smalltalk-Entwicklung bei Xerox, Alan Kay, finanziert seit den 90ern die Entwicklung einer frei verfügbaren Smalltalk Implementierung namens Squeak, die für die Entwicklung von Multimedia Anwendungen gedacht ist.