[ 1 ] [ 2 ]

Aufteilung in verschiedene Klassen

Entsprechend der Analyse einer Aufgabe werden verschiedene Klassen erstellt. In diesen Klassen wird die Funktionalität nochmals in verschiedene Ebenen verteilt. In den Methoden der dadurch entstandenen Struktur werden nur noch die jeweils notwendigen Teilaufgaben gelöst. Dies bedeutet, dass in den Methoden keine komplexen Funktionen abgebildet werden müssen. Das wiederum kann sich bei einer späteren Erweiterung durch Vererbung und anschließende Anpassung als Vorteil herausstellen.

    Define Class Element_Base As Custom
       ...
       *===========================================================
       * Erstellen einer Methode, in der in den Ableitungen die
       * notwendige Funktionalität eingetragen wird.
       *===========================================================
    Function Create()
       Return
    EndDefine
    Define Class Element_Menu As Element_Base
    ...
    *==========================================================
       * In einer Ableitung, in der das Menü verwaltet werden soll,
    * wird in der Methode der notwendige Code zum Aktivieren des
          * Systemmenüs eingetragen.
       *===========================================================
       Function Create()
          SET SYSMENU TO
          SET SYSMENU AUTOMATIC
       Return
       ...
    EndDefine
    Define Class Element_Pad As Element_Base
    ...
    *==========================================================
    * In einer Ableitung, in der ein Pad verwaltet werden soll,
          * wird in der Methode der notwendige Code zum Erstellen eines
          * Pads eingetragen.
       *===========================================================
       Function Create()
             DEFINE PAD _msm_file OF _MSYSMENU PROMPT "\<File"      
       Return
       ...
    EndDefine
    usw.....

Fazit

Bei der Aufteilung auf verschiedene Klassen erhöht sich zwar der Aufwand bei der Erstellung (es müssen mehr Klassen angelegt werden), aber der Codeumfang innerhalb der jeweiligen Methode Create reduziert sich auf ein Minimum. Bei der Variante „alles in einer Klasse“ erscheint der Code in der Methode Create im Vergleich dazu als umfangreiches Programm.  

Schritt 3: Die Realisierung

Die Klassen und ihre Abhängigkeiten

Abbildung 3

Die Abbildung 3 zeigt die Klassen mit den entsprechenden Abhängigkeiten untereinander. In dem Diagramm werden zwei Arten von Abhängigkeiten dargestellt. Zum einen ist das die Vererbung ( Custom à MenuBase à MenuExecuter ... ), zum anderen kommt die Aggregation von Klassen ( CollectionBase ßà MenuBase ) zum Einsatz. Einfach gesagt, bedeutet dies nichts anderes, als dass die Objekte nicht von einander abgeleitet werden, sondern miteinander verknüpft werden. Um komplexe Objektstrukturen zu erstellen, ist es sinnvoll, eine Kombination beider Varianten zu verwenden.

 

Methoden und Eigenschaftsnamen

Bei der Wahl eines Namens  für eine Methode hat sich bei vielen Entwicklern schon durchgesetzt, dass der Datentyp als erste Stelle angegeben wird. Auch bei Methoden kann eine solche Klassifizierung unter Umständen sinnvoll sein. Beispiele dafür sind: 

DoXxxxxx – Methode, die bei Bedarf in der Ableitung durch spezialisierten Code überschrieben  wird. Beim Klassendesign wird nur eine unbedingt notwendige Grundfunktionalität zur Verfügung  gestellt. 

EventXxxxxx – Hook, um in Ableitungen auch in komplexen Methoden einzugreifen. 

IsXxxxxx – Prüfen einer Bedingung. Es wird immer True oder False zurückgegeben

MenuBase

Diese Klasse ist die Grundlage für alle anderen Menüelemente. In dieser Klasse wird das grundlegende Interface  definiert, über das später auf jedes Menüelement zugegriffen werden kann.

Methoden und Eigenschaften:

DoCreate() / DoRemove() -

erstellen und entfernen des jeweiligen Elementes aus dem Menü. 

DoShow() / DoHide() -

bieten die Möglichkeit, einzelne Elemente anzuzeigen bzw. zu verstecken.

EventActivate() / EventDeactivate() -

sind Ereignisse, die von der Klasse beim Aktivieren bzw. Deaktivieren eines Elements ausgelöst werden

cElementId -  

enthält den eindeutigen Namen eines Elements, mit dem im Menü auf das Element zugegriffen werden kann.

cMessage - 

enthält den Text, welcher in der Statuszeile angezeigt wird.

MenuExecuter

Im MenuExecuter werden die Aufgaben spezialisiert, die das Ausführen von Aufgaben ermöglichen.

Methoden und Eigenschaften:

AddPopup() -

Definiert für Elemente in dieser Gruppe, welches Popup bei einer Auswahl durch einen Anwender aktiviert werden soll.

AddCommand() -

Definiert die Aufgabe, die bei einer Auswahl durch den Anwender ausgeführt werden soll.

 

 

cCaption -

Enthält die Bezeichnung, die für das Element im Menü angezeigt werden soll.

cKey -

Enthält den Hotkey, der für das Menü verwendet werden soll.

cParentElementId -

Enthält die Namen der Popups bzw. der Menüzeile, in dem das Element eingebunden ist.

MenuCollection

In der Klasse wird die Verbindung zwischen dem Interface eines Menuelementes ( Klasse MenuBase ) und der Funktionalität einer Collection hergestellt. Das Codebeispiel zeigt einen Auszug aus der Klasse, in der eine  solche Verknüpfung realisiert wird.
  

    *===========================================================
    * In der Klasse wird das Interface (die Methoden Add und Remove
    * sowie die Eigenschaften Item und Count) der Collectionklasse
    * implementiert. Wird eine Methode bzw. Eigenschaft verwendet,
    * dann werden die entsprechenden Aufrufe bzw. Zugriffe an
    * die Collection weitergegeben.
    *===========================================================
    Define Class MenuCollection As
          Dimension   Item[1]
         count       = 0
    ...
       Function Init()
          This.AddObject("oCollection","CollectionBase")
          ...
       Return
    Function Item_Access()
       Return This.oCollection.Item(tuItem)
       Function coun_Access(tuId)
       Return This.oCollection.Item(tuItem)
       Function Add(tuItem)
       Return This.oCollection.Add(tuItem)
       Function Remove(tuItem)
       Return This.oCollection.Remove(tuItem)
       ...
    EndDefine

Methoden und Eigenschaften:

Add() -

fügt der Collection einen neuen Wert hinzu.  

Remove() -

entfernt einen Eintrag aus der Collection.

Item -

ist ein Array, in dem die einzelnen Einträge der Collection verwaltet werden sollen.

Count -

enthält die aktuelle Anzahl der Einträge in einer Collection.

MenuMenu, MenuPopup, MenuBar und MenuPad

In diesen Klassen wird das Interface eines allgemeinen Elementes mit dem jeweils notwendigen VFP – Code versorgt. Auf Basis der Klassen MenuMenu und MenuPopup können die entsprechenden Menüobjekte erstellt werden. 

CollectionBase

Diese allgemein zu verwendende Klasse bietet die Möglichkeit, einzelne Elemente in einem Array zu verwalten. Es besteht die Möglichkeit, auf diese Elemente über einen Index zuzugreifen. Weiterhin können der Collection  Elemente hinzugefügt werden bzw. auch wieder entfernt werden.

Methoden und Eigenschaften:

Add() -

Fügt der Collection einen neuen Wert hinzu.  

Remove() -

Entfernt einen Eintrag aus der Collection.

Item -

ist ein Array, in dem die einzelnen Einträge der Collection verwaltet werden sollen.

Count -

enthält die aktuelle Anzahl der Einträge in einer Collection.

CmdExecuter

Auch bei dieser Klasse handelt es sich um keine spezielle Menüklasse. Mit Hilfe dieser Klasse besteht die Möglichkeit, verschiedene Funktionalitäten als ein Objekt an ein weiteres Objekt weiterzugeben. Bei dem Menü – Objekt wird diese Möglichkeit genutzt, um Aktionen an den MenuExecuter zu übergeben.

Methoden und Eigenschaften:

DoExecute -

führt den in einer Ableitung hinzugefügten VFP – Code aus.

cCommand

enthält eine Befehlszeile, die ausgeführt wird, wenn die Methode DoExecute nicht überschrieben wurde. 

Zusammenfassung

Wie sie sehen, ist es gar nicht so schwer, mit den VFP – eigenen Mitteln ein Menüobjekt zu erstellen. Warum es in VFP noch keine OO – Menüs gibt, wird wohl weiterhin ein Geheimnis bleiben .......

Die aktuelle Version der hier beschriebenen Klasse finden Sie im Internet unter www.Prolib.de/DevCon2000.

Sollten Sie Fragen oder Anregungen zu der Klasse oder der Session haben, stehe ich gern auf der Konferenz bzw. unter  PeterS@Prolib.defür weitere Gespräche zur Verfügung.

 

[ 1 ] [ 2 ]