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 ausge­stattet 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.