Autor Thema: Lotus Script + Objektorientierte Programmierung + Methodenaufruf der Superklasse  (Gelesen 4010 mal)

Offline Skorpi

  • Junior Mitglied
  • **
  • Beiträge: 79
  • Geschlecht: Männlich
Hallo Leutz,

folgendes Szenario:

Mal angenommen es existieren zwei Klassen Person und Mitarbeiter. Wobei die Mitarbeiter-Klasse von der Personen-Klasse erbt. Nun habe ich folgendes Problem. Wenn ich bei dem Mitarbeiter-Objekt die Methode save aufrufe, wird leider nicht die gleichnamige Methode der Superklasse (in diesem Fall Person) aufgerufen. Bei der Methode new hingegen funktioniert der automatische Aufruf der Methode in der Superklasse.

Hat jemand eine Lösung für das Problem.

Die Klassen:

Code
Public Class Person
	
	Private doc As NotesDocument	
	Private strVorname As String
	Private strNachname As String	
	
	Sub new(doc As NotesDocument)
		If Not doc Is Nothing Then
			Set Me.doc = doc
			Me.strVorname = doc.GetItemValue("vorname")(0)
			Me.strNachname = doc.GetItemValue("nachname")(0)
		End If
	End Sub
	
	Property Get Vorname As String
		Vorname = Me.strVorname
	End Property	
	
	Property Set Vorname As String
		Me.strVorname = Vorname
	End Property
	
	Property Get Nachname As String
		Nachname = Me.strNachname
	End Property
	
	Property Set Nachname As String
		Me.strNachname = Nachname
	End Property
	
	Sub save
		Call Me.doc.ReplaceItemValue("vorname", Me.Vorname)
		Call Me.doc.ReplaceItemValue("nachname", Me.Nachname)		
		Call Me.doc.save(True,False,False)
	End Sub
	
End Class

Public Class Mitarbeiter As Person
	
	Private intPersonalnummer As Integer
	
	Sub new(doc As NotesDocument)
		If Not doc Is Nothing Then
			Me.intPersonalnummer = Cint(doc.GetItemValue("personalnummer")(0))
		End If
	End Sub
	
	Property Get Personalnummer As Integer
		Personalnummer = Me.intPersonalnummer
	End Property
	
	Property Set Personalnummer As Integer
		Me.intPersonalnummer = Personalnummer
	End Property	
	
	Sub save
		Call Me.doc.ReplaceItemValue("personalnummer", Me.Personalnummer)		
		Call Me.doc.save(True,False,False)
	End Sub
	
End Class

Zum Testen habe ich den folgenden Agenten angelegt:

Code
Sub Initialize
	
	Dim session As New NotesSession
	Dim db As NotesDatabase	
	Dim docMitarbeiter As NotesDocument
	
	Set db = session.CurrentDatabase	
	
	Set docMitarbeiter = New NotesDocument(db)
	docMitarbeiter.Form = "Mitarbeiter"
	Call docMitarbeiter.ReplaceItemValue("vorname", "Max")
	Call docMitarbeiter.ReplaceItemValue("nachname", "Mustermann")
	Call docMitarbeiter.ReplaceItemValue("personalnummer", 1234)
	Call docMitarbeiter.Save(True,False,False)
	
	Dim ma As New Mitarbeiter(docMitarbeiter)
	
	Print ma.Vorname 'Ausgabe: Max
	Print ma.Nachname 'Ausgabe: Mustermann
	Print ma.Personalnummer	'Ausgabe: 1234
	
	ma.Vorname = "Maxi"
	ma.Nachname = "Musterfrau"
	ma.Personalnummer = 4321
	
	Call ma.Save
	
	Set ma = New Mitarbeiter(docMitarbeiter)
	
	Print ma.Vorname 'Ausgabe: Max <------ kein Maxi
	Print ma.Nachname 'Ausgabe: Mustermann <------ kein Musterfrau
	Print ma.Personalnummer	'Ausgabe: 4321
	
End Sub
Gruß

Fabian

Glombi

  • Gast
Aus der Hilfe:

Accessing base-class properties and methods
A derived class can call a property or method in a base class, even if that method was overridden in the derived class. You use two dots (dotdot notation) to access a base class’s overridden method. Dotdot notation is valid only in class scope (within a Class statement).
The syntax is:
baseClassName..propertyName (parameters)
or
baseClassName..methodName (parameters)
For example, you can override a method just to add additional processing. You would call the base class’s method and then do the extra processing in the derived class method.

Andreas
« Letzte Änderung: 15.08.07 - 16:16:43 von Glombi »

Offline flaite

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 2.966
    • mein del.icio.us
Das ist in Java, VB.NET, C# und C++ nicht anders.
Die Idee von overwriding ist ja gerade, dass genau die Methode des Runtime-Types aufgerufen wird.
In Java kann man Methoden von Super-Klassen mit super.<methodenName> aufrufen.

Die Konstruktoren werden demgegenüber auch in Java, VB.NET,  C# und vermutlich auch C++ der Reihe nach aufgerufen. Und zwar angefangen beim Konstruktor der obersten Super-Klasse. Das ist konzeptionell korrekt, weil ja Mitarbeiter is a Person und dann muss eben auch der Konstruktor von Person initialisiert werden, wenn du einen Mitarbeiter willst. Mit den Methoden ist das aber was anderes. Meist will man da gar nicht, dass die Methoden der Super-Klasse aufgerufen werden. Konstruktoren sind eben was anderes als Methoden.

Objektorientiertes JavaScript kennt übrigens überhaupt keine Vererbung, wobei es da Tricks gibt, das zu simmulieren, aber das nur am Rande.

Und nun wirds völlig Offtopic und bezieh das jetzt bitte nicht auf dich:
Ich glaub, dass das von Bob Balaban oder einem anderen Entwickler der Sprache LotusScript erstellten OO-Features von LotusScript falsch eingesetzt werden. Irgendwie fehlt da ein bischen eine Unterscheidung zwischen Domain Driven Design (das heisst ein komplettes OO-Modell zu erstellen) und einfach die netten Features des Schlüsselwortes "class" zu nutzen.
Ich nutz z.B. eine Menge das Konstrukt class, seh das aber oft nicht als Objektmodell sondern als eine Art Skript-Library, die einen Satz von Funktionen und Variablen hat, die für die Objekte der Klasse global sind, aber ausserhalb nicht gesehen werden können.
Der Zweck ist nicht die "reale Welt abzubilden", weil das nicht geht. Es geht vielmehr darum Duplizierung von Code zu vermeiden. 

Ich hab hier z.B. 4 Buttons in einer per store-form-in-Document an eine Usermail geschickt werden. Der User erzeugt darüber eine Mail, die an eine Mail-In-DB geht. Es werden spezielle Felder in der Mail gesetzt, dafür Werte aus der einkommenden Mail ausgelesen, in manchen Fällen gibt der User was in den Prompt-Boxen ein. In 2 Fällen wird die Mail direkt aus dem Button versendet, in anderen Fällen öffnet sich ein neues UIDoc per Uiws.editDocument mit ein paar Backend-Feldern, die im Code des Buttons da reingesetzt wurden. Und gerade für solche typischen Domino-Fälle kann man imho mit einer Klasse viel einfacheren und übersichtlicheren Code schreiben.
Anstatt also das Thema OO mit dem Anspruch zu begegnen, nun die Welt zu modellieren, könnte man sich vielleicht auch überlegen, einfach mal für typische Aufgaben eine Klasse zu schreiben. Mit dem bescheidenen Ziel übersichtlichen Code zu schreiben, in dem NICHTS dupliziert ist. Anfänger werden da Fehler machen. Aber imho lohnt es sich. Und wenn man da ein bischen Sicherheit gewinnt, die Nachteile kennenlernt, etc.. Dann kann man versuchen Domains in Klassen zu modellieren. Das ist aber ziemlich schwierig.

Das mehr als eigene späte Erkenntnis und Anregung und nicht als rant.   

 Gruß Axel
« Letzte Änderung: 15.08.07 - 17:32:13 von Axel Janssen »
Ich stimm nicht mit allen überein, aber mit vielen und sowieso unterhaltsam -> https://www.youtube.com/channel/UCr9qCdqXLm2SU0BIs6d_68Q

---

Aquí no se respeta ni la ley de la selva.
(Hier respektiert man nicht einmal das Gesetz des Dschungels)

Nicanor Parra, San Fabian, Región del Bio Bio, República de Chile

Offline Skorpi

  • Junior Mitglied
  • **
  • Beiträge: 79
  • Geschlecht: Männlich
Guten morgen,

erstmal vielen Dank für die schnelle und sehr gute Hilfe. Irgendwie schäm ich mich nur ein bisschen, dass ich die Antwort (dotdot notation) nicht selbst in der Hilfe gefunden habe. Mehr zum Thema Klassen und LotusScript befindet sich in der Hilfe unter dem Inhaltspunkt: LotusScript Language -> User-Defined Data Types and Classes

Also die Lösung mit der dotdot notation sieht dann im obigen Beispiel wie folgt aus:

Code
Public Class Mitarbeiter As Person
	
	...
	
	Sub save
		Call Me.doc.ReplaceItemValue("personalnummer", Me.Personalnummer)		
		Person..save ' --> ruft die Methode der Save der Klasse Person auf
	End Sub
	
                ...

End Class

Das ganze funktioniert genau so wie ich mir das vorgestellt habe und wie ich es aus meiner Zeit als Java-Entwickler kenne.

@Axel

Da gebe ich dir Recht, es ist natürlich nicht sinnvoll die reale Welt bis in das kleinste Detail abzubilden. Vielmehr lassen sich bestimmte Dinge (ob das nun Objekte der realen Welt oder eine Zusammenfassung von Funktionen sind, ist egal) sinnvoll in Klassen zusammenfassen. Die durch den richtigen Einsatz der objektorientierten Programmierung entstehenden Klassen-Hierarchien (Vererbung) und -Beziehungen unterstützen den Entwickler bei der Erstellung komplexer Anwendungen.
Gruß

Fabian

Offline flaite

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 2.966
    • mein del.icio.us
@Skorpi,

I have just discovered...

für mich gibt es 2 Arten des Einsatzes des Schlüsselwortes "class" in LotusScript:

1. Der Versuch die gesamte business Domain als Objekte abzubilden.
2. Bestimmte, eng fokussierte technische Aufgabenstellungen wie z.B. das Auslesen von HTTP-Parametern in Lotus-Web Agenten, das Handling von Business Logik,  die an Button Clicks in einer Maske gebunden ist, etc.

Das zweite ist ein weniger ambitionierter Hybridansatz. Die Datenstrukturen und Algorithmen müssen dabei nicht Objekte sein. Nur für bestimmte, eng fokussierte Aufgaben werden Klassen geschrieben.

Beide Ansätze das class feature in LotusScript zu nutzen sind sehr unterschiedlich.

Ich glaube nicht, dass Klassen in komplexeren Anwendungen wirklich helfen. Nicht zuletzt deshalb, weil in Lotus Notes Anwendungen die den Business Case bedienenden Datenstrukturen schon in DOKUMENTEN gespeichert sind. Und Dokumente sind etwas freaking anderes als Objekte im OO-Verständnis. Will man die gesamte business  Domain als Objekte darstellen, müsste man die Dokumente auf die Objekte mappen und das schafft eine eigene Komplexität.

Viel effektiver erscheint mir da schon Ansatz 2. Ein Entwickler kennt sich in einer technischen Domäne sehr gut aus. Etwa die Verarbeitung von HTTP-Parametern in Web-Agenten. Der kann die Logik in Skriptbibliotheken schreiben oder dafür Klassen verwenden. Und Klassen bringen da Vorteile,  völlig losgelöst von jeder Objekt Orientierten Analyse, die auf die business domain abzielt.

Nachdem ich über einen langen Zeitraum fast nur noch Java programmiert habe und jetzt wieder 1 LotusScript und 1 LotusScript/JavaScript Projekt betreue sind mir diese Überlegungen gekommen. Ich benutze zwar viel CLASS, mach aber keine objekt orientiert Analyse im Sinne von etwa Domain Driven Design.
Im Codestore blog hat der Autor auch "class" in diesem enge-technische-Domain-Sinne für sich entdeckt (z.B. http://www.codestore.net/store.nsf/unid/BLOG-20070815?OpenDocument oder http://www.codestore.net/store.nsf/unid/BLOG-20070814/

Ich hijacke hier natürlich ziemlich diesen Thread. 

Vom Tooling des Domino Designer her werden user defined classes kaum unterstützt. Mit dem freien Teamstudio Script browser (try  google) gibts aber inzwischen zumindest ein funktionierendes "Inspektionstool", dh. es listet automatisch die Membervariablen und Methoden von user defined classes auf. Theoretisch kann man mit ANTLR (google) selbst einen LotusScript Parser, Lexer,  etc schreiben, mit dessen output man dann eigenes Tooling für LotusScript und sogar Formelsprache Designelemente in einer Lotus Notes Datenbank schreiben kann. Das Eclipse  basierte openSource Projekt "Domiclipse" hat genau damit angefangen.

Gruß Axel

Gruß Axel
« Letzte Änderung: 16.08.07 - 09:49:02 von Axel Janssen »
Ich stimm nicht mit allen überein, aber mit vielen und sowieso unterhaltsam -> https://www.youtube.com/channel/UCr9qCdqXLm2SU0BIs6d_68Q

---

Aquí no se respeta ni la ley de la selva.
(Hier respektiert man nicht einmal das Gesetz des Dschungels)

Nicanor Parra, San Fabian, Región del Bio Bio, República de Chile

 

Impressum Atnotes.de  -  Powered by Syslords Solutions  -  Datenschutz