Klasse oder Modul

  • VB.NET

Es gibt 18 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    Klasse oder Modul

    Hallo Leute!

    Der "lästige" hat wieder eine Grundsatzfrage.
    Dass man so weit wie möglich Klassen zur strukturierten Auslagerung von Funktionen benutzen sollte ist mir klar. Was Klassen sind und wie die vom Grundsatz her funktionieren ist mir auch klar.

    Anhand eines kleines Beispiels möchte ich Euch fragen, ob dafür ein Modul nicht doch besser geeignet ist:

    In Modul:

    VB.NET-Quellcode

    1. Public Module Hauptmodul
    2. Private Sub warten(Sekunden As Double)
    3. Dim ZeitSpanne As Double
    4. Dim Start As Double
    5. ZeitSpanne = Sekunden / 100000
    6. Start = DateTime.Now.ToOADate() ' Anfangszeit setzen.
    7. Do While DateTime.Now.ToOADate() < Start + ZeitSpanne
    8. Application.DoEvents() ' Steuerung an andere Prozesse abgeben
    9. Loop
    10. End Sub
    11. End Module


    In Klasse:

    VB.NET-Quellcode

    1. Public Class Class_AllgemeineFunktionen
    2. Function warte(Sekunden As Double) As Boolean
    3. Dim ZeitSpanne As Double
    4. Dim Start As Double
    5. ZeitSpanne = Sekunden / 100000
    6. Start = DateTime.Now.ToOADate() ' Anfangszeit setzen.
    7. Do While DateTime.Now.ToOADate() < Start + ZeitSpanne
    8. Application.DoEvents() ' Steuerung an andere Prozesse abgeben
    9. Loop
    10. Return True
    11. End Function
    12. End Class


    Aufruf von Modul und Klasse. Das Ergebnis ist das selbe, nur der Aufruf über das Modul ist weniger Code und dadurch überschaubar

    VB.NET-Quellcode

    1. ...
    2. frm_about.Label2.Text = "Jetzt warten wir einmal 2 Sekunden ..."
    3. 'Klassenaufruf
    4. Dim EigeneFunktionen As New Class_AllgemeineFunktionen
    5. EigeneFunktionen.warte(2) '2 Sekunden warten
    6. 'Modulaufruf
    7. warten(2) '2 Sekunden warten
    8. frm_about.Label2.Text = "Danke für das Warten"
    9. ...


    Dabei geht es bitte jetzt nur um die Grundsatzfrage Klasse oder Modul, nicht um die Wartefunktion selbst - die wurde schon in einem anderen Thread behandelt.

    LG Roland
    Liebe Grüße
    Roland Berghöfer

    Meine aktuellen und kostenlos verwendbaren Tools (mit VB.NET erstellt): freeremarkabletools.com | priconman.com | SimpleCalendar | AudibleTouch | BOComponent.com | bonit.at

    MSDN schrieb:

    Eine Module-Anweisung definiert einen Verweistyp, der im gesamten Namespace verfügbar ist. Ein Modul (zuweilen auch als Standardmodul bezeichnet)ähnelt einer Klasse, doch bestehen einige wichtige Unterschiede. Jedes Modul verfügt über genau eine Instanz und muss weder erstellt noch einer Variablen zugewiesen werden. Module unterstützen keine Vererbung und implementieren keine Schnittstellen. Beachten Sie, dass ein Modul kein Typ in dem Sinn ist, in dem eine Klasse oder Struktur ein Typ ist – Sie können ein Programmierelement nicht mit einem Datentyp Modul deklarieren.

    Module kann nur auf Namespaceebene verwendet werden. Dies bedeutet, dass der Deklarationskontext für ein Modul eine Quelldatei oder ein Namespace sein muss und keine Klasse, keine Struktur, kein Modul, keine Schnittstelle, keine Prozedur und kein Block sein kann. Sie können Module nicht in anderen Modulen und auch nicht in einem Typ schachteln. Weitere Informationen finden Sie unter Deklarationskontexte und Standardzugriffsebenen (Visual Basic).

    Ein Modul verfügt über die gleiche Lebensdauer wie das Programm. Da alle seine Member Shared sind, entspricht deren Lebensdauer ebenfalls der Lebensdauer des Programms.

    Sagt doch eigentlich schon alles oder?

    und hier kannsten och mehr über Module Lesen: msdn.microsoft.com/de-de/libra…xss7da%28v=vs.100%29.aspx
    Es gibt in VB keinen Grund, Module zu nutzen, es sei denn, Du implementierst Extensions.

    Weiterhin gibt es keinen Grund, ein Programm künstlich in einen Wartezustand zu versetzen. Auch wenn Du es nicht hören magst. Wer hat Dir gesagt, dass Application.DoEvents() irgend eine Steuerung an andere Prozesse abgibt? Application.DoEvents verarbeitet höchstens Meldungen in der Warteschlange und der Loop treibt die CPU-Auslastung hoch. Ist umgangssprachlich bekannt als Ranz. VB.Net ist eventgesteuert. Es wartet ohnehin auf Interaktion, da gibt es nur wenige Fälle, wo ein künstlicher Wartezustand angebracht ist. Für diese Fälle gibt es verschiedene Arten von Timern.
    Die Unendlichkeit ist weit. Vor allem gegen Ende. ?(
    Manche Menschen sind gar nicht dumm. Sie haben nur Pech beim Denken. 8o

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „SpaceyX“ ()

    Dein Beispiel würde ich mit einer Statischen Funktion erstellen

    VB.NET-Quellcode

    1. Public Class Class_AllgemeineFunktionen
    2. Shared Function warte(Sekunden As Double) As Boolean
    3. Dim ZeitSpanne As Double
    4. Dim Start As Double
    5. ZeitSpanne = Sekunden / 100000
    6. Start = DateTime.Now.ToOADate() ' Anfangszeit setzen.
    7. Do While DateTime.Now.ToOADate() < Start + ZeitSpanne
    8. Application.DoEvents() ' Steuerung an andere Prozesse abgeben
    9. Loop
    10. Return True
    11. End Function
    12. End Class

    Aufruf:

    VB.NET-Quellcode

    1. frm_about.Label2.Text = "Jetzt warten wir einmal 2 Sekunden ..."
    2. 'Klassenaufruf
    3. Class_AllgemeineFunktionen.warte(2) '2 Sekunden warten
    4. frm_about.Label2.Text = "Danke für das Warten"


    lg
    ScheduleLib 0.0.1.0
    Kleine Lib zum Anlaufen von Code zu bestimmten Zeiten
    Ich stelle mir Module vorallem in der Wartung kritisch vor. Da man Ihre Methoden direkt aufrufen kann, muss man ständig im Kopf behalten, welches Modul welche Methoden beinhaltet. Schau dann mal nach nem Jahr wieder drauf, und du bist ständig am suchen^^ und so haste die Klassennamen dabei, schafft Ordnung und übersicht, und die vier Buchstaben + einen Tab die du Mehr tippst machen den Kohl auch nicht Fett.
    Danke fichz,

    Das geht also auch kürzer. Vielen Dank für den Code.

    Aber bis auf "dudu - kein Modul verwenden" macht es bei diesem Beispiel wohl keinen Unterschied ob Modul oder Klasse ?

    Liege ich damit richtig: Wenn diese Funktion von verschiedenen Programmteilen aufgerufen werden könnte (z.B. in einem parallelem Thread), dann Klasse. Wenn eine Routine jedoch nur stringent ohne zeitliche Überschneidung aufgefufen wird, kann man (für dieses oder ein ähnliches Beispiel) ebenso ein Modul verwenden. Ich bin Praktiker - und wenn etwas das selbe bewirkt - der Code weder schneller noch langsamer ist und die Lesbarkeit nicht darunter leidet, wo liegt dann der Unterschied?

    @Spaceyx - unnötiger Kommentar.

    Ich stelle mir Module vorallem in der Wartung kritisch vor. Da man Ihre Methoden direkt aufrufen kann, muss man ständig im Kopf behalten, welches Modul welche Methoden beinhaltet. Schau dann mal nach nem Jahr wieder drauf, und du bist ständig am suchen^^
    und so haste die Klassennamen dabei, schafft Ordnung und übersicht, und die vier Buchstaben + einen Tab die du Mehr tippst machen den Kohl auch nicht Fett.


    Die paar Buchstaben mehr sind kein Problem. So viel ist es ja nicht. Aber auch Module kann man so bennen, dass man in 10 Jahren noch weis was die machen.
    Modulname: mdl_AllgemeineFunktionen
    Prozedurname: Warte


    Wäre Schreib- und Erkennungstechnisch kein Unterschied: ;)

    VB.NET-Quellcode

    1. Class_AllgemeineFunktionen.warte(2)
    2. mdl_AllgemeineFunktionen.Warte(3)


    Ich wehre mich nicht gegen den Einsatz von Klassen, aber ich möchte auch verstehen, warum alle bei solch einfachen Prozeduren Module als "Teufelswerk" hinstellen. Ich bins halt so von VB6 gewohnt. Und wenn für mich der Quelltext dadurch überschaubarer wird und ich meinem Ziel (dem fertigen Programm) schneller näher bringt, warum sollte ich es dann nicht so machen?

    LG Roalnd
    Liebe Grüße
    Roland Berghöfer

    Meine aktuellen und kostenlos verwendbaren Tools (mit VB.NET erstellt): freeremarkabletools.com | priconman.com | SimpleCalendar | AudibleTouch | BOComponent.com | bonit.at
    Mir geht es eher darum, dass man die Modulfunktionen im gesamten Namespace ohne Nennung des Moduls aufrufen kann, sodass da schnell mal die übersicht verloren geht, ausser due schreibst sie dann so wie Klassen, doch dann könntest du auch gleich Klassen nehmen, da sie zukunftssicherer sind, willst du doch mal mit Interfaces Arbeiten oder Vererben, was Module, laut zitat oben ebend nicht können.
    Ich verwende beides.

    Ich habe meistens sogar mehrere Module in einem Program.
    z.B. lagere ich im Modul "PublicVariablen" Variablen aus die ich im Programm überall brauche.
    Oder im "Dirty_Modul" Lagere ich Option-Strickt-Off Methoden aus.
    There is no CLOUD - just other people's computers

    Q: Why do JAVA developers wear glasses?
    A: Because they can't C#

    Daily prayer:
    "Dear Lord, grand me the strength not to kill any stupid people today and please grant me the ability to punch them in the face over standard TCP/IP."
    Außerdem würde dir bei der Benutzung auch direkt die Umsetzbarkeit in C# erhalten bleiben oder anders gesagt: In C#, dem großen kleinen Bruder von VB (neuer aber mit mehr Funktionen und von den meisten benutzt) gibt es auch keine Module, also kannst du es auch gleich lassen.
    Mir erschließt sich nach wie vor nicht, wozu du jemanden 2 Sekunden auf nichts warten lassen willst. nenn mir bitte mal ein praktisches Beispiel, in dem Es nötig ist, einen Anwender auf etwas warten zu lassen, anstatt ihm sofort nach irgendeiner Interaktion etwas anzeigen zu lassen.

    Ebenso erschließt sich mit nicht ganz der sinn deiner Schleife.

    das "Dirty_Modul" :D
    @nafets3646:

    Das stimmt nicht. In C# gibt es Static, was dem VB-Modul wohl ziemlich nahe kommt.

    @dive26:

    Es dreht sich hier eigentlich um die Frage, ob Du Deine alten VB6-Gewohnheiten loslassen willst. Es ist nicht nur eine einfache Frage ob Klasse oder Modul, sondern es ist eher die Frage nach OOP oder nicht. OOP bringt Dir im weiteren Verlauf viel mehr praktischen Nutzen. Das geht auch einher mit einem Umschwenken in der Denkweise. Befasse Dich mal etwas ausführlicher mit OOP und die Frage nach einem Modul wird sich Dir nicht mehr stellen. Liegt an Dir.
    Die Unendlichkeit ist weit. Vor allem gegen Ende. ?(
    Manche Menschen sind gar nicht dumm. Sie haben nur Pech beim Denken. 8o

    VB.NET-Quellcode

    1. Class_AllgemeineFunktionen.warte(2) '2 Sekunden warten


    Funktioniert doch nicht!

    VB.NET-Quellcode

    1. Dim EigeneFunktionen As New Class_AllgemeineFunktionen
    2. EigeneFunktionen.warte(2)


    Dies Funktioniert. Also nehme ich mein geliebtes Warte-Modul :rolleyes:
    Liebe Grüße
    Roland Berghöfer

    Meine aktuellen und kostenlos verwendbaren Tools (mit VB.NET erstellt): freeremarkabletools.com | priconman.com | SimpleCalendar | AudibleTouch | BOComponent.com | bonit.at
    Man sollte Leuten einfach nicht helfen die so ignorant sind. Der TE möchte seine schlechten Gewohnheiten, die absolut unbrauchbaren und schlecht wartbaren Code produzieren, beibehalten und will von OOP nichts hören.

    Entweder gehst du auf die Antworten ein, oder bleib bei VB6.
    Module sind das, was in C# statische Klassen sind. Wer sich den resultierenden IL anschaut, wird das auch sehen.
    Deshalb sind Module immer dann zu verwenden, wenn man in C# eine statische Klasse verwenden würde.
    VB unterscheidet sich da nur Syntaktisch von C#: Die einzelnen Klassenmember müssen nicht alle noch einmal angeben, dass sie statisch (Shared/static) sind. Außerdem muss man keinen Modulnamen angeben, wenn man eine Funktion aus einem Modul verwenden will (was ich ziemlich blöd finde, ist aber so).

    Dieses Modul:

    VB.NET-Quellcode

    1. Module MeinModul
    2. Public Sub Funktion()
    3. ' ...
    4. End Sub
    5. End Module
    6. ' Verwendung:
    7. Funktion()


    ...würde in C# so aussehen:

    C-Quellcode

    1. static class MeinModul
    2. {
    3. public static void Funktion()
    4. {
    5. // ...
    6. }
    7. }
    8. // Verwendung:
    9. MeinModul.Funktion();

    Beides hat nahezu identischen IL-Code (beim Modul ist noch ein Attribut dran, aber das kann man vernachlässigen). Es gibt in VB.NET deshalb auch keine andere Möglichkeit Extension Methods zu erstellen, als mit Modulen.

    Aber warum keine nicht-statische Klasse anstatt eines Moduls verwenden?
    Um ein ähnliches Verhalten wie in C# zu erzeugen sieht man häufig sowas:

    VB.NET-Quellcode

    1. Class MeinModul
    2. Public Shared Sub Funktion()
    3. ' ...
    4. End Sub
    5. End Class
    6. ' Verwendung:
    7. MeinModul.Funktion()

    Das funktionert so auch, hat aber den "Nachteil", dass auch Instanzfunktionen möglich sind. Außerdem hat diese klasse einen Default-Konstruktor (Sub New()), der durch Zauberei vielleicht irgendwo aufgerufen werden könnte. Dafür kann man bei dieser Methode vererbung anwenden (warum gibt es eigentlich keine statische Vererbung?). Den Konstruktor sollte man auch - sofern man ihn nicht benötigt - Private oder Protected machen:

    VB.NET-Quellcode

    1. Class MeinModul
    2. Private Sub New()
    3. ' nichts
    4. End Sub
    5. Public Shared Sub Funktion()
    6. ' ...
    7. End Sub
    8. End Class
    9. ' Verwendung:
    10. MeinModul.Funktion()
    ...um zu verhindern, dass irgendjemand davon Instanzen erstellt.

    Module haben übrigens auch einen Konstruktor. Dieser ist einfach nur ein statischer Konstruktor, den es bei normalen, nicht-statischen Klassen auch gibt.


    Edit:
    Übrigens würde ich die Warten-Funktion imt einem Callback definieren. Spart Ressourcen und ist einfach sauberer.

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Friend Module AllgemeineFunktionen
    2. Sub Warte(seconds As Integer, callback as Action)
    3. Dim tmr as New Timer()
    4. tmr.Interval = seconds * 1000
    5. AddHandler tmr.Tick, Sub(e, s)
    6. tmr.Stop()
    7. callback()
    8. End Sub
    9. tmr.Start()
    10. End Sub
    11. End Module
    12. ' Aufruf:
    13. frm_about.Label2.Text = "Jetzt warten wir einmal 2 Sekunden ..."
    14. Warte(2, Sub()
    15. frm_about.Label2.Text = "Danke für das Warten"
    16. End Sub)
    17. ' bzw:
    18. Warte(2, AddressOf SubName)

    Von meinem iPhone gesendet

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „nikeee13“ ()

    nikeee13 schrieb:

    Module sind das, was in C# statische Klassen sind.
    Nicht ganz, es gibt einen feinen Unterschied. Member von Modulen in VB kann man von überall her aufrufen, ohne das Modul mit anzugeben, bei Membern einer statischen Klasse in C# geht das nicht, da muss man die Klasse immer vorneanstellen. Ich glaube aber, das hat eher was mit dem Compiler zu tun, nicht mit dem IL-Code.

    Artentus schrieb:

    Member von Modulen in VB kann man von überall her aufrufen, ohne das Modul mit anzugeben
    Das habe ich oben bereits geschrieben. Es handelt sich dabei einfach um eine Eigenheit der Sprache. Irgendwer hat gesagt "so machen wir das". Es ist allerdings auch nur in VB.NET so. Will man eine VB.NET-Modulfunktion in einem C#-Programm verwenden, so muss man den Modulnamen angeben.
    VB schaut dabei nur auf das von mir oben genannte Attribut. Sobald eine Klasse damit beklebt ist, ist es für VB.NET ein Modul, bei dem man den Namen nicht mehr angeben muss.

    Übrigens löst der Compiler das vollständig auf, d. h. im IL wird explizit auf die Funktion via Modulname (bzw. Klassenname) zugegriffen.
    Von meinem iPhone gesendet

    dive26 schrieb:

    Aber bis auf "dudu - kein Modul verwenden" macht es bei diesem Beispiel wohl keinen Unterschied ob Modul oder Klasse ?
    Ganz genau erkannt: es macht keinen Unterschied, ausser dass sich dogmatisch angehauchte Leuts drüber aufregen. :thumbsup:

    (normale Klasse ist sogar bisserl ungünstiger, weil man immer erst mit New instanzieren muß - also 2 Zeilen braucht, wo Modul oder statische Methode direkt aufrufbar wären.)
    Mit dogmatisch meine ich, dass losgeschimpft wird, ohne eine wirkliche Begründung zu liefern, warum nu eine Klasse oder ein Singleton soo viel besser wäre.
    AFAIK werden Module wirklich in statische Klassen übersetzt, also es ist wirklich die c#-Entsprechung einer static class.
    Aber ebenso richtig ist, dasses in c# besser gelöst ist, nämlich, dass nicht jede Methode einer static class von überall direkt zugreifbar ist.
    Dem kann man in diesem Fall mit einem Namespace abhelfen, aber wenn das Modul eh nur eine Methode enthält, wird dadurch auch nix gewonnen, weil dann ist die Methode zwar verborgen, dafür hat man aber einen neuen Namespace rumfahren inne Intellisense.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „ErfinderDesRades“ ()