Objektorientiert programmieren
TwinCAT 3 unterstützt die objektorientierte Programmierung (OOP) und stellt dafür die folgenden Funktionalitäten und Objekte zur Verfügung:
- Funktionsbausteine (Objekt Funktionsbaustein)
- Methoden (Objekt Methode)
- Eigenschaften (Objekt Eigenschaft)
- Schnittstellen (Objekt Schnittstelle, Implementieren einer Schnittstelle)
- Vererbung
- Definition von Funktionsbausteinen als Erweiterungen anderer Funktionsbausteine
- Definition von Strukturen als Erweiterungen anderer Strukturen
- Definition von Schnittstellen als Erweiterungen anderer Schnittstellen
- Methodenaufruf
- ABSTRACT-Konzept
Grundgedanke der objektorientierten Programmierung
Bei der objektorientierten Programmierung wird die Software in Objekte unterteilt. Dabei werden alle Beschreibungen, die zu diesem Objekt gehören, in einem Element (z. B. in einem Funktionsbaustein) zusammengeführt. Die Beschreibungen umfassen dabei die Daten und die Prozeduren, über die das Objekt verfügen soll. Zudem kann über Methoden und Eigenschaften eine ausgewählte Zugriffsschnittstelle auf das Objekt definiert werden.
Dadurch werden bei diesem Programmieransatz Objekte entwickelt, die autark und unabhängig von spezifischen Rahmenbedingungen wiederverwendet werden können. Dabei können die Elemente beispielsweise in einer oder vielen Applikationen unverändert zum Einsatz kommen.
Vorteile der objektorientierten Programmierung
Die Verwendung der objektorientierten Programmierweise bietet viele Vorteile.
Durch die Einteilung der Software in Objekte kann eine übersichtliche, gut strukturierte Applikation entwickelt werden. Dadurch sind die Applikation und die einzelnen Elemente optimalerweise leicht und verständlich lesbar sowie leicht erweiterbar. Zusammen mit der geschaffenen Wiederverwendbarkeit von Programmierobjekten können bei der Entwicklung und Wartung von Applikationen letztlich Zeit und Kosten gespart werden.
Allgemeine Hinweise/Empfehlungen
- Bei der Verwendung der objektorientierten Programmierung ist darauf zu achten, für die jeweilige Applikation den richtigen „Grad der Objektorientierung“ zu finden.
- Mit Hilfe von OOP wird die Software in Objekte unterteilt, sodass eine übersichtliche, strukturierte, wiederverwendbare Software entwickelt werden kann.
- Falls die Einteilung der Objekte jedoch exzessiv und sehr detailliert vorgenommen wird, leidet die Verständlichkeit des Programms.
- Beispiel: Mit Hilfe der Vererbung können Deklarationen und Implementierungen vererbt und somit von der Unterklasse wiederverwendet werden. Zudem kann durch die Einteilung in eine generelle und eine spezifische Klasse das Verständnis für die einzelnen Programmierobjekte unterstützt werden. Dies ist bei der Vererbung dann der Fall, wenn die Einteilung in Basis und Erweiterung schlüssig ist und sich beispielsweise in der realen Welt gleichermaßen oder ähnlich wiederfinden lässt (z. B. Basismotor und speziellerer Motor mit Zusatzfunktionen). Falls jedoch sehr viele Vererbungsebenen verwendet werden und die Funktion der einzelnen Vererbungslevel dadurch unklar bzw. unpräzise wird, ist dieser Teil der Applikation schwer zu verstehen und zu warten.
- Wenn Methoden Rückgabewerte liefern, sollten diese in der Methode gesetzt und an der Aufrufstelle der Methode ausgewertet werden.
- Wenn Methoden, Funktionen oder Eigenschaften strukturierte Rückgabetypen liefern (z. B. eine Struktur oder einen Funktionsbaustein), sollten diese Rückgabetypen als „REFERENCE TO <structured type>“ deklariert werden.
- Das Zurückliefern von strukturierten Daten als direkter Rückgabetyp („<structured type>“) ist ineffizient, da die Daten mehrfach kopiert werden.
- Wenn stattdessen „REFERENCE TO <structured type>“ verwendet wird, ist dies zum einen effizienter, da die Daten nicht kopiert werden, und zum anderen kann auf ein einzelnes Element des strukturierten Datentyps direkt beim Aufruf der Methode/Funktion/Eigenschaft zugegriffen werden.
- Weitere Informationen und ein Beispiel finden Sie u. a. in der Beschreibung Objekt Methode.
- Die Programmierung von objektorientierten Implementierungen sollte eventbasiert sein.
- Programmelemente sollten nicht grundlos zyklisch aufgerufen werden.
- In der Regel ist ein Aufruf eines Programmelements dann sinnvoll, wenn ein bestimmtes Ereignis eingetreten ist.
- Ein Methoden- oder Eigenschaftenaufruf über eine nicht belegte Schnittstellenvariable gleicht einem NullPointer-Aufruf. Vor der Verwendung der Schnittstellenvariablen muss ihr eine entsprechende Funktionsbausteininstanz zugewiesen werden (Instanz eines Funktionsbausteins, der die Schnittstelle implementiert).
- Um sicherzugehen, dass die Schnittstellenvariable keinem NullPointer entspricht, kann die Schnittstellenvariable vor der Verwendung auf ungleich 0 überprüft werden (z. B.
IF (iSample <> 0) THEN iSample.METH(); END_IF
).
OOP und UML
Müssen die objektorientierte Programmierung (OOP) und UML stets zusammen verwendet werden?
- Die kombinierte Nutzung von OOP und UML bietet viele Vorteile (s. nächste Frage), ist allerdings nicht zwangsläufig nötig. Es ist auch ohne die Verwendung von UML möglich, eine Applikation objektorientiert zu programmieren. Genauso kann UML auch in SPS-Projekten verwendet werden, die nicht objektorientiert programmiert werden bzw. wurden.
Welche Vorteile bietet es, OOP und UML zusammen zu verwenden?
- Um die Vorteile der OOP optimal zu nutzen, sollte die Struktur einer objektorientierten Software vor Implementierungsbeginn konzipiert bzw. erstellt werden (z. B.: Welche Klassen sind vorhanden, in welcher Beziehung stehen sie zueinander, welche Funktionalitäten stellen sie bereit, etc.). Vor, während und nach der Programmierung helfen Dokumentationen dabei, die Software zu verstehen, zu analysieren und zu warten.
- Als Analyse-, Design- und Dokumentationswerkzeug von Software bietet UML entsprechende Möglichkeiten, um die Applikation zu planen, zu erzeugen und zu dokumentieren. Dabei eignet sich die Verwendung von UML besonders bei objektorientierten Implementierungen, da vor allem modular aufgebaute Software mithilfe einer grafischen Sprache dargestellt werden kann.
- So wird beispielsweise das Klassendiagramm zum Analysieren und Erzeugen der Programmstruktur verwendet – und je modularer die Software aufgebaut ist, desto einfacher und effizienter kann das Klassendiagramm genutzt werden (z. B.: Grafische Darstellung von separaten Funktionsblöcken mit einzelnen Methoden zur Bereitstellung der Funktionalitäten, etc.).
- Das Zustandsdiagramm kann genutzt werden, um den Ablauf eines ereignisdiskreten Systems zu spezifizieren – und je konsequenter die Software objekt- bzw. ereignisorientiert aufgebaut ist, desto übersichtlicher und effektiver können Zustandsmaschinen entworfen werden (z. B.: Das Verhalten von Modulen/Systemen basiert auf einem Zustandsmodell mit Zuständen (wie Aufstarten, Produktion, Pausezustand) und innerhalb der Zustände werden entsprechende Funktionalitäten aufgerufen, die in Methoden (wie Aufstarten, Ausführen, Pausieren) gekapselt sind, etc.).
Siehe auch:
- Dokumentation zu: TF1910 TC3 UML
- Dokumentation Samples: Beispiel: Objektorientiertes Programm zur Steuerung einer Sortieranlage