Kompositon - eine zentrale Technik der OOP
demonstriert am Beispiel einer einfachen Robotersimulation
Diese Fallstudie knüpft an die Fallstudie mit dem Titel „Robotersimulation – ein einfaches Beispiel für OOP-Anfänger“ an (s. OOP-Beispiel (1)). Sie sollten deshalb jenes Beispiel studieren, bevor Sie das vorliegende angehen.
Im ersten Beispiel hatten wir einen Roboter benutzt, der nur mit drei Bewegungsbefehlen ausgestattet war
- einen Schritt vorwärts
- Drehung um 90 Grad nach links
- Drehung um 90 Grad nach rechts.
Diese Befehle betrachteten wir, so wie die übrigen Basisbefehle des Roboters auch, als fest verdrahtet und deshalb nicht veränderbar.
Im vorliegenden Beispiel geht es nun darum, den Roboter auch mit umfangreicheren Befehlen zu benutzen. Wir wollen das tun, ohne den Roboter selbst umzubauen, was ja vereinbarungsgemäß auch nicht möglich ist. Stattdessen schaffen wir eine Zwischeninstanz, welche die vom Benutzer abgesetzten umfangreicheren Befehle in Abfolgen von Basisbefehlaufrufen umsetzt.
Unter den vielen möglichen umfangreicheren Befehlen wollen wir die folgenden herausgreifen:
- Wenden (also eine Drehung um 180 Grad)
- Ansteuern eines vorgegebenen Punkts (x, y) auf der Bewegungsebene des Roboters
- Rückkehr zum Depot, also zum anfänglichen Standort des Roboters
Die zusätzlichen Steuerungsmöglichkeiten sollen natürlich vom Steuerpult aus wahrgenommen werden können. Hier ist das neue Steuerpult:

Da wir eine Zwischeninstanz einbauen, welche die zusätzlichen Befehle in Abfolgen von Basisbefehlen umsetzt, wird aus der ursprünglich vorhandenen Zweischichtarchitektur nun eine dreischichtige Architektur:

Im Diagramm ist die Zwischeninstanz als „programmierbarer Roboter“ bezeichnet. Programmtechnisch handelt es sich um eine Klasse namens pRobot. Sie enthält u.a. Prozeduren für die oben genannten drei Befehle wenden, Ansteuern eines Punkts und Zurückkehren, und sie lässt sich problemlos um weitere Befehle erweitern. Möglich sind aber immer nur Befehle, welche sich in Abfolgen der Basisbefehle vor, rechts und links umwandeln lassen.
Die Klasse pRobot und die Technik der Komposition
Bei der Programmierung der Klasse pRobot kommt eine fundamentale Technik der OOP zur Anwendung, nämlich die der Komposition (aus dem englischen Composition). Komposition hat hier nicht die Bedeutung eines von einem Komponisten geschaffenen Musikstücks, sondern steht einfach für „Zusammenstellung“ bzw. „Zusammensetzung“. Eine Komposition in der OOP ist eine Klasse, die aus Objekten anderer Klassen zusammengestellt bzw. zusammengebaut ist, die also Objekte anderer Klassen enthält.
Die Klasse pRobot ist eine solche Komposition, allerdings eine sehr einfache. Sie enthält nämlich ein Objekt der Klasse robot. Realisiert ist dies durch die Deklaration einer Instanzenvariablen vom Typ robot. Diese Instanzenvariable verkörpert den zu steuernden Basisroboter. An sie werden innerhalb der Prozeduren der Klasse pRobot die Basisbefehle gerichtet, welche aus der Umsetzung der erweiterten Befehle resultieren.
Betrachten wir nun den (fragmentarischen) Code der Klasse pRobot. Die Deklaration der Instanzenvariablen r vom Typ robot befindet sich gleich in der ersten Zeile. Daneben gibt es noch zwei weitere globale Variablen dx und dy, die jedoch keine Objekte bezeichnen, sondern die Koordinaten der Anfangsposition des Roboters („Depot“). Wir müssen diese Koordinaten aufbewahren, denn sie werden für den Befehl „zum Depot zurückkehren“ (Methode zurueck) gebraucht.
Private r As robot
Private dx As Integer, dy As Integer
'Anfangspositionierung
Public Sub setStatus(ByVal xstart As Integer, _
ByVal ystart As Integer, _
ByVal dirstart As String)
Set r = New robot
r.setStatus xstart, ystart, dirstart
dx = xstart
dy = ystart
End Sub
'Basisbefehle
'------------------
Public Sub einsvor()
r.einsvor
End Sub
Public Sub rechts()
r.rechts
End Sub
Public Sub links()
r.links
End Sub
Public Function getX() As Integer
getX = r.getX
End Function
Public Function getY() As Integer
getY = r.getY
End Function
Public Function getDir() As String
getDir = r.getDir
End Function
'Zusatzbefehle, auf den Basisbefehlen aufbauend
'----------------------------------------------------------------------
'Drehung um 180 Grad
Public Sub wenden()
r.rechts
r.rechts
End Sub
'Bewegung zu vorgegebenem Punkt
'Public Sub geheNach(ByVal xneu As Integer, ByVal yneu As Integer)
' ……………………………
'End Sub
'bewegt Roboter zum Depot zurück
Public Sub zurueck()
' ……………………………
End Sub
Beachten Sie, dass die Klasse pRobot nicht nur Methoden für die umfangreichen Befehle an den Roboter benötigt, sondern auch für die Basisbefehle. Nur so kann ein pRobot-Objekt als alleiniger Adressat für die vom Steuerpult kommenden Befehle fungieren.
Die Methoden, die den Basisbefehlen entsprechen, sind allerdings sehr einfach. Der Befehl wird einfach an das robot-Objekt weitergereicht, zusammen mit den notwendigen Parameterwerten.
Von den Zusatzbefehlen ist hier nur einer voll ausprogrammiert, das Wenden bzw. die 180-Grad-Drehung. Dies sollte genügen, um das Prinzip der Programmierung auf der Grundlage von Basisbefehlen klar zu machen. Bei den übrigen Zusatzbefehlen ist der Code ausgespart und durch eine Folge von Punkten ersetzt. Ich möchte Sie dazu einladen, diese Teile selbst zu programmieren.
Die Klasse RobotForm2 (das Steuerpult)
Gegenüber der ursprünglichen Fassung der Fallstudie gibt es an zwei Stellen Veränderungen zu vermerken:
- Die Instanzenvariable rob ist nun vom Typ pRobot und nicht mehr vom Typ robot
- Es sind drei Ereignisprozeduren für die Zusatzbefehle wenden, geheNach und zurueck hinzugekommen.
Hier ist der Code der Klasse RobotForm2:
Private rob As pRobot
Private Sub UserForm_Initialize()
Set rob = New probot
rob.setStatus 10, 10, "s"
Statusanzeige
End Sub
Private Sub Statusanzeige()
Me.xTBx.Text = CStr(rob.getX)
Me.yTBx.Text = CStr(rob.getY)
Me.dirTBx.Text = rob.getDir
Me.nachxTBx.Text = CStr(rob.getX)
Me.nachyTBx.Text = CStr(rob.getY)
End Sub
Private Sub vorBtn_Click()
rob.einsvor
Statusanzeige
End Sub
Private Sub linksBtn_Click()
rob.links
Statusanzeige
End Sub
Private Sub RechtsBtn_Click()
rob.rechts
Statusanzeige
End Sub
Private Sub wendenBtn_Click()
rob.wenden
Statusanzeige
End Sub
Private Sub geheNachBtn_Click()
rob.geheNach CInt(Me.nachxTBx.Text), CInt(Me.nachyTBx.Text)
Statusanzeige
End Sub
Private Sub zurueckBtn_Click()
rob.zurueck
Statusanzeige
End Sub
Übrigens kommt auch in der Klasse RobotForm2 die oben erläuterte Kompositionstechnik zur Anwendung, denn RobotForm2 enthält das Objekt rob der Klasse pRobot.