Domino 9 und frühere Versionen > ND9: Entwicklung

Suche Lösungsansatz für dynamisches Klassenmapping

(1/1)

khing:
Hallo,

ich habe verschiedene kleine Klassen dich ich nur initialisieren möchte und darin immer die gleiche Funktion aufrufe z. B. so:

--- Code: ---Dim vObject = MeineKlasse1   'MeineKlasse2 usw.
Set vObject = New MeineKlasse1(vNotesDocument) 'Datentyp NotesDocument soll übergeben werden
Call vObject.Run()

--- Ende Code ---
Welche der Klassen aufgerufen wird, soll mittels eines Formular entschieden werden. Also steht dies erst zur Laufzeit fest.

Da ich ich davon ausgehe, dass die Anzahl dieser kleinen Klassen immer mehr werden, wollte ich mir ein Mapping ersparen. Mit der Funktion Execute bin ich leider auch nicht weiter gekommen, da diese keine Objekte zurückgibt. Nun kann ich sicher alle Klassen Public setzen und das Call vObject.Run() im Execute ausführen aber wäre auch nicht so schön  ::) (zumal die Klassen Public sein müssten).

Ich hoffe, dass ich mich einigermaßen verständlich ausgedrückt habe...  ;) Kennt ihr eine Möglichkeit das (besser) zu lösen?

Vielen Dank und schönen Feierabend.

Gruß Kristian

MadMetzger:
Man kann in Lotus Script Vererbung, Polymorphie und eine Anlehnung an das Pattern Fabrikmethode für die Lösung deines Problems nutzen:

1. Schaffe eine Oberklasse zu deinen MeineKlasseX, nennen wir Sie MeineOberKlasse
2. In der Oberklasse erstelle eine Methode Run(), die nichts tut.
3. Deine Meine Klasse leitet von MeineOberKlasse ab und implementiert die Methode Run(). Wenn ich mich recht erinnere ging das etwa so:

--- Code: ---Class MeineKlasseX As MeineOberklasse
...

--- Ende Code ---
4. Für die dynamische Auswahl der richtigen MeineKlasse erstellst du dir eine Function, die dir kontextabhängig eine Instanz der richtigen Unterklasse zurückgibt. Das ist dann die Fabrikmethode, wie eingangs erwähnt.

ERR:
Hallo Kristian,

per Execute ist es auch machbar. Im Internet gibt es diese Beispiele zu finden ("Dynamic Lotusscript"). Hier ist meine Umsetzung dazu.

Zuerst eine Scriptbibliothek anlegen (z.B. "libNewObj") und dort die zwei globale Variablen in Declarations definieren:


--- Code: ---Private vntFactories List As Variant
Public vntNewObj_factory As Variant

--- Ende Code ---

Dann diese Funktion in die Scriptblibliothek einfügen:


--- Code: ---Function fktNewObj( strClassName As String ) As Variant

'Fehlerbehandlung
On Error GoTo Error_Handler
'
'Variablendeklaration
Dim strScript As String
'
'Prozedur
If Not IsElement(vntFactories(strClassName)) Then
strScript = |
Use "| & strClassName & |"
Sub Initialize
Set vntNewObj_factory = New | & strClassName & |Factory
End Sub
|
Execute (strScript)
Set vntFactories(strClassName) = vntNewObj_factory
End If

Set fktNewObj = vntFactories(strClassName).produce

e:

Exit Function

Error_Handler:
Set fktNewObj = Nothing

'... hier entsprechendes Error-Handling einfügen

Resume e
End Function

--- Ende Code ---

In jeder deiner Scriptbibliotheken muss dann zusätzlich zu deiner Klasse eine weitere (Mini-)Klasse angelegt werden:

--- Code: ---Class MeineKlasse1Factory

Function produce As Variant
Set produce = New MeineKlasse1
End Function

End Class

--- Ende Code ---

In der Maske oder auch z.B. einem Agent muss in den Options

--- Code: ---Use "libNewObj"

--- Ende Code ---

eingefügt werden und dann per Aufruf der Funktion fktNewObj verwendet werden:

--- Code: ---Dim strKlasse As String

' Variable mit dem Klassennamen setzen (in deinem Beispiel z.B. aus einem Feldwert)
strKlasse = "MeineKlasse1"

' neues Objekt zu der Klasse erzeugen
Set objMeineKlasse1 = fktNewObj(strKlasse)

' Methode der Klasse im Objekt aufrufen
Call objMeineKlasse1.Run()

--- Ende Code ---

Leider können keine Parameter direkt übergeben werden, aber das kann man umgehen, in dem man in der jeweiligen Klasse eine "Init"-Funktion anlegen und die dann per


--- Code: ---objMeineKlasse1.Init(doc, view, Param3, Param4, ...)

--- Ende Code ---

zuweist.

MFG
ERR

Navigation

[0] Themen-Index

Zur normalen Ansicht wechseln