Domino 9 und frühere Versionen > Entwicklung
Wie kann ich eine Klasse sinnvoll aufbauen ?
animate:
--- Zitat von: TMC am 06.07.04 - 22:09:01 ---Habe es aber jetzt so verstanden:
Ich muss also in der Basisklasse (hier = abstrakte Klasse) die Function/Sub genau so reinschreiben (Function / End Function), aber nur ohne Code dazwischen. Nur dann kann ich dann auch auf die Unterklassen - Function/Sub zugreifen.
--- Ende Zitat ---
jein.
1. In der Methode der abstrakten Klasse kann sehr wohl auch Funktionalität implemetiert sein. Funktionalität, die in allen Subklassen benötigt wird (damit du nicht redundanten Code hast).
Diese Methode in der Basisklasse
Sub doIt()
Print "Basisklasse"
End Sub
und diese in der Subklasse
Sub doIt()
Call Basisklasse..doIt()
Print "Subklasse"
End Sub
2. (aber nicht groß drüber nachdenken, ist nicht so wichtig und verwirrt an dieser Stelle wohl nur) Du musst die Methode nicht zwingend in der Basisklasse haben.
TMC:
--- Zitat von: Thomas Völk am 06.07.04 - 22:17:52 ---2. (aber nicht groß drüber nachdenken, ist nicht so wichtig und verwirrt an dieser Stelle wohl nur) Du musst die Methode nicht zwingend in der Basisklasse haben.
--- Ende Zitat ---
Dann hab ich das glaub ich richtig verstanden (nur nicht verständlich rübergebracht).
Genau das war mein Ziel:
- Wiederkehrendes an 1 Stelle (hier: abstrakte Klasse)
- Spezielles in die abgeleiteten Klassen
- Der Call aber immer gleich (wenn ich Call sportauto.Feature mache, soll sich die Lachgaseinspritzung einschalten, wenn ich Call cabrio.Feature mache, soll sich das Dach öffnen).
TMC:
OK, ich stecke nun mittendrin.
Damit das nun überhaupt noch wer kapiert von was ich rede, hole ich etwas weiter aus:
Wir haben als Aufgabe, Feldänderungen einer Maske in eine History zu schreiben.
Um das zu machen, habe ich
+ alle Feldnamen
+ alle Feldtitel (die ja abweichen können vom Feldnamen, z.B. Titel "Inhalt", Name aber "Sbj1")
+ alle Feldinhalte
jeweils in einem Array.
Um z.B. das Array "Feldinhalte" zu erzeugen, nutze ich eine Function:
Private Function ExtItemValuesToArray(doc As NotesDocument, vFieldList As Variant) As Variant
Nun sagt Thomas zurecht: Du hast ja da eine ScriptLib, wo Du Felder behandelst, mach doch daraus eine Klasse "Field".
--- Zitat ---Ein Objekt der Klasse 'Feld' repräsentiert genau ein zu überwachendes Feld aus dem Notesdokument.
D.h., wenn ich drei Felder überwachen will, dann brauche ich drei Objekte. Jedes Objekt kann mir Auskunft darüber
geben, welchen Wert 'sein' Feld hat, welchen es ürsprünglich hatte bzw. worin der Unterschied zwischen den beiden Werten besteht.
--- Ende Zitat ---
Das mache ich auch jetzt dann.
Mein Problem ist jetzt:
Ich muss ja den einzelnen Objekten u.a. Feldinhalte geben.
Bisher mach ich es mir einfach.
--- Code: ---Private Function ExtItemValuesToArray(doc As NotesDocument, vFieldList As Variant) As Variant
'**************************************************************************************************
'Purpose: Loops through the provided field list and puts the item values to an Array
'
'In case of RichTextField, it sets a prefix "I_AM_A_RTF" and the last modified date. So we
'are easily able to find out if the array-entry-source was richtext.
'**************************************************************************************************
On Error Goto ERRORHANDLER
Dim item As NotesItem
Dim vItemValues() As Variant
Dim strItemValue As String
Dim i As Integer
'We loop through the field list and set the item values to the HistorySourceArray
Redim vItemValues(Ubound(vFieldList))
For i = 0 To Ubound(vFieldList)
Set item = doc.GetFirstItem( vFieldList(i) )
If item.Type = RICHTEXT Then
vItemValues(i) = "I_AM_A_RTF" & Cstr(item.LastModified)
Else
'--> We find out if the item contains more than one value; if so: we put 'em together in a string
strItemValue = ""
Forall v In item.values
If strItemValue = "" Then
strItemValue = Cstr(v)
Else
strItemValue = strItemValue & " / " & Cstr(v)
End If
End Forall
'<--------------
vItemValues(i) = strItemValue
End If 'item.Type = RICHTEXT Then
Next
ExtItemValuesToArray = vItemValues
EXITSCRIPT:
Exit Function
ERRORHANDLER:
Call AuxErrorHandler("ExtItemValuesToArray")
Resume EXITSCRIPT
End Function
--- Ende Code ---
Damit mache ich mir ein Array aus den Feldinhalten eines Dokumentes. Ich sehe dabei auch sofort, ob ein Array-Eintrag aus einem RT-Feld stammt und kann das dann weiterbearbeiten.
Unser Zielanspruch ist aber, mehrere Unterklassen zu haben (FieldText, FieldRTF, etc.).
Wie gebe ich jetzt die Feldinhalte in die Klassen FieldText und FieldRTF?
Ich müsste dann ja im Code abfragen, um was es sich für ein Feld handelt, und dann die entsprechende Klasse erstellen.
Dann habe ich eine Ansammlung an Objekte als Ergebnis: Einige FieldText-Objekte und einige FieldRTF-Objekte (kunterbunt gemischt).
Bisher war die Ausgabe der Reihenfolge in die Historie vorgegeben durch die Reihenfolge im Array. Jetzt muss ich wohl zusätzlich noch einen Zähler mitlaufen lassen um die Reihenfolge zu beizubehalten.
Außerdem blähe ich so den Code auf in dem ich die Objekte erstelle. All das hatte ich mit der Function vermieden.
Fazit:
Mittlerweile sehe ich nicht mehr so ganz den Sinn, eine Field-Klasse zu erstellen um z.B. obengenannte Function abzulösen.
Aber vielleicht kann mir das wer erklären (wenn da jetzt überhaupt noch wer durchsteigt ::) )
Danke
TMC:
Hier noch ein wenig Code als Ansatz für die Field-Klasse.
a) Die abstrakte Klasse
--- Code: ---Public Class HistoryField2
Private m_vInitialValue As Variant
Private m_vNewValue As Variant
Private m_strTitle As String
Private m_vDifference As Variant
'-------------------------------------------------------------------------------------------------
'Get/Set-Methoden
Public Property Set NewValue As Variant
m_vNewValue = NewValue
End Property
Public Property Get Difference As Variant
Difference = getDifference(m_strTitle, m_vInitialValue, m_vNewValue)
End Property
'-------------------------------------------------------------------------------------------------
Public Sub new(strTitle As String, vInitialValue As Variant)
m_strTitle = strTitle
m_vInitialValue = vInitialValue
End Sub
'-------------------------------------------------------------------------------------------------
Private Function getDifference(strName As String, vSource As Variant, vTarget As Variant) As String
'Nichts. Code wird in der abgeleiteten Klasse ausgeführt !
End Function
'-------------------------------------------------------------------------------------------------
End Class
--- Ende Code ---
b) Eine Unterklasse
--- Code: ---Public Class HistoryField2Text As HistoryField2
%REM
Diese Klasse nutzt die abstrakte Klasse "HistoryField2 !
%END REM
'-------------------------------------------------------------------------------------------------
Public Sub new(strName As String, vInitialValue As Variant)
End Sub
'-------------------------------------------------------------------------------------------------
Private Function getDifference(strName As String, vSource As Variant, vTarget As Variant) As String
Dim strResult As String
If vSource = vTarget Then
Else 'Nein, Quelle und Ziel sind nicht identisch
strResult = AuxImplode(vSource, " / ") 'erstmal alles in ein String
strResult = AuxRemoveLinebrakes(strResult, " ")
strResult = "Changed Field '" & strName & "' (former value: '" & strResult & "')"
End If
End Function
'-------------------------------------------------------------------------------------------------
End Class
--- Ende Code ---
Hier brauch ich aber noch eben die ursprünglichen Feldinhalte, und dann auch die neuen Feldinhalte.
TMC:
Kommando zurück:
Ich habe glaub ich den Fehler gemacht, auf den bisherigen Code was aufzusetzen.
Was imho besser wäre, nochmal neu anzufangen.
- Man hat ein Dokument und öffnet dieses
- dabei schreibt man pro zu überwachendes Feld was in ein FieldObjekt (Name, Inhalt, etc.)
- Beim Speichern schreibt man zusätzlich die neuen Werte in die FieldObjekte und lässt sich die Unterschiede geben.
Der bisherige Codeteil ist dafür nicht wirklich brauchbar.
Ich glaube das beste ist es das ganze nochmal neu aufzusetzen.
Navigation
[0] Themen-Index
[#] Nächste Seite
[*] Vorherige Sete
Zur normalen Ansicht wechseln