Sauberes Programmieren

  • VB.NET

Es gibt 6 Antworten in diesem Thema. Der letzte Beitrag () ist von hal2000.

    Sauberes Programmieren

    Hey,

    heute habe ich mal kein Programmierproblem sondern mal eine Fragestellung zu sauberer Programmierweise.

    Ich habe mir VB.Net (das was ich da kann ist 100% ausbaufähig) selber bei gebracht und aus VBA transferiert etc.
    Ein Stück weit ordentlich programmieren habe ich in meiner Ausbildung gelernt, aber nie in VB.Net

    Jetzt während meines Studiums zum Betriebswirten WI lerne ich VB.Net und mein Lehrer wirft alles über den Haufen, was ich den letzten Jahren mir selber beigebracht hat.

    VB.NET-Quellcode

    1. Public Sub sub_SQL_Protokoll(pint_Typ As Integer, pstr_Meldung As String, Optional pstr_Modul As String = "--default--", Optional pstr_Prozedur As String = "--default--")
    2. Dim ole_CON As New OleDbConnection(SYSVAR_DBCon)
    3. Dim ole_CMD As New OleDbCommand
    4. Try
    5. ole_CON.Open()
    6. ole_CMD.CommandText = "INSERT INTO stab_Protokoll (Art, Modul, Prozedur, Beschreibung) VALUES (" & pint_Typ & ", '" & pstr_Modul & "', '" & pstr_Prozedur & "', '" & pstr_Meldung & "')"
    7. ole_CMD.Connection = ole_CON
    8. ole_CMD.ExecuteNonQuery()
    9. Catch ex As Exception
    10. sub_Meldung(ex.Message, Warnstufe.Fehler)
    11. sub_Datei_Protokoll(ex.Message & vbNewLine & "+++ Eigentliche Meldung +++" & vbNewLine & pstr_Meldung, "mod_System" & " >>> Eigentliches Modul:" & vbTab & pstr_Modul & "sub_SQL_Protokoll" & " >>> Eigentliche Prozedur:" & vbTab & pstr_Prozedur)
    12. Finally
    13. ole_CON.Close()
    14. End Try
    15. End Sub


    Ich habe gelernt vor den meisten Dingen irgendein Prefix zu schreiben um auf einen Blick zu sehen, welcher Datentyp es ist und wo es deklariert wurde.

    str_Test heißt es ist ein String der lokal in der Methode dimensioniert wurde
    pstr_Test ist auch ein String, allerdings ein Parameter (dafür ein p vorm Datentypprefix) und wird im Methodenkopf genutzt
    gstr_Test auch ein String, jedoch global deklariert.

    Zum besseren Lesen trenne ich den Datentypen mit einem Unterstrich vom Variablennamen, ähnlich bei den Methoden sub_ oder fct_

    Ebenso handhabe ich das in Datenbanken. stab für Systemtabellen (hier ändern sich keine/minimal Daten), tab für normale Tabellen und vw für eine View.

    Ist das nicht eine Abwandlung der ungarischen Notation?

    In der Schule lerne ich jetzt komplett auf Prefix und Unterstrich verzichten zu müssen. Mit der Maus kann doch über eine Variable gezeigt werden um zu sehen, welcher Datentyp es ist.
    Wie unterscheiden sich dann Variablen von Methoden und umgekehrt?

    Könnt ihr mir bitte verraten, was jetzt richtig ist. Gewinnen wirklich die faulen Programmierer, die lieber mit der Maus einer müllersche Wanderung durch den Code machen????

    kurzda schrieb:

    was jetzt richtig ist
    Es gibt da kein richtig oder falsch. Jeder macht das so, wie er es mag. Fertig.

    kurzda schrieb:

    Wie unterscheiden sich dann Variablen von Methoden und umgekehrt?
    Variablen speichern Werte im Arbeitsspeicher und Methoden machen irgendetwas. Variablen können jedoch nicht den Typ Sub bzw. void (in C#) annehmen.

    LG :)

    kurzda schrieb:

    str_Test heißt es ist ein String der lokal in der Methode dimensioniert wurde
    pstr_Test ist auch ein String, allerdings ein Parameter (dafür ein p vorm Datentypprefix) und wird im Methodenkopf genutzt
    gstr_Test auch ein String, jedoch global deklariert.


    Es gibt in jeder Sprache Konventionen an welche man sich halten sollte um die Lesbarkeit zwischen den Programmierern zu gewährleisten.
    Mir wurde im Studium auch beigebracht einen Präfix vor die Variablen zu schreiben, was ich dann nachdem ich erstmals ausserhalb des Studiums programmiert hatte wieder über den Haufen geworfen habe, da dies überbleibsel der untypisierten Programmierung sind bzw. waren.

    Im .NET Framework sollte im normalfall Typsicherheit herrschen wodurch man relativ schnell erkennen kann um welche Art von Variablen es sich handelt.

    HIER findest du offizielle dinge seitens MS zu den Programmier Konventionen.


    kurzda schrieb:

    Zum besseren Lesen trenne ich den Datentypen mit einem Unterstrich vom Variablennamen, ähnlich bei den Methoden sub_ oder fct_


    Im Prinzip wie oben.

    kurzda schrieb:

    In der Schule lerne ich jetzt komplett auf Prefix und Unterstrich verzichten zu müssen. Mit der Maus kann doch über eine Variable gezeigt werden um zu sehen, welcher Datentyp es ist.
    Wie unterscheiden sich dann Variablen von Methoden und umgekehrt?


    Variablen reservieren und zeigen auf einen Speicherplatz in deinem RAM in welchem du Werte speichern und lesen kannst.

    Methoden sind in VB.NET Sub's und Function's. Eine Function besitzt im Gegenteil zu einer Sub einen Rückgabewert.

    Ich habe mir dieses hier mal angesehen und für ganz gut befunden :)
    Enthält eig. alles zu den Grundlagen und relativ viele praktische Beispiele.
    Richtig oder falsch gibt es nicht. Es gibt Meinungen, Ansichten, Vor- und Nachteile, Vorlieben und vieles mehr.
    Faulheit hat den Vorteil, einfache Ergebnisse zu produzieren. Einfachheit ist (zumindest aus meiner Sicht) ein gutes Ziel beim Programmieren. Komplexe Regeln sind aber halt nicht einfach...

    Vom Kerngedanken war die ungarische Notation nicht dazu gedacht, einfach den Datentyp vor dem Namen einer Variable zu schreiben, sondern vielmehr den Wert näher zu spezifizieren.
    Zum Beispiel die Länge eines Strings: Ist die Anzahl der Bytes oder der Zeichen gemeint? Beides sind ohne Zweifel Ganzzahlen und jeder würde einen Integer nehmen. Doch sind beide Angaben Grundverschieben und ein Vergleich von beiden wäre in den aller meisten Fällen nicht wirklich sinnvoll. Die Idee bei Präfixen war es, solche Vergleiche sofort zu bemerken, nicht das was man heute noch häufiger sieht.

    Ich nehme mal deinen Code Stück für Stück auseinander und liste mal ein paar Dinge auf, die meiner Meinung nach vom Stil besser sein könnten. Das ist wie oben angemerkt natürlich nicht unbedingt richtiger als dein Stil, aber hat gewisse Vorteile (wie auch eventuell Nachteile).

    1) MS hat mit .NET einen Guide zur Namenskonvention eingeführt. Dort steht z.B. das Bezeichner für Methoden im CamelCase-Stil erfolgen sollen. Also jedes neue Wort Groß angefangen, keine Unterstriche und Abkürzungen i.d.R. auch klein nach dem Ersten Zeichen. Da das durchgängig im kompletten Framework so ist, sind die meisten Programmierer beim Schreiben und Lesen von Quellcode daran gewöhnt. Entsprechend sticht z.B. sub_SQL_Protokoll hier deutlich raus. Das ist gut im Sinne von "man erkennt was Framework und eigene Code ist", aber es ist auch ein ziemlicher Umbruch der halt auch stören kann.

    2) Ist es wirklich wichtig, ob es sich um eine Sub oder eine Funktion handelt? Technisch gesehen ist der einzige Unterschied, dass ersteres keinen Rückgabewert besitzt, letzteres aber schon. Die Information ist natürlich wichtig, aber ist sie immer notwendig zu wissen, wenn ich den Namen der Funktion sehe oder schreibe?
    Was ist wenn du eine Sub in eine Funktion umwandelst? (Zugegeben, VS hilft hier enorm dank Refactoring). Was passiert wenn du eine Methode (im Sinne von Funktion oder Sub) aufrufen möchtest, aber gerade nicht weißt, ob es eine Sub oder eine Funktion ist? (IntelliSense hilft hier natürlich; funktioniert aber noch besser ohne Präfix.)

    3) sub_SQL_Protokoll: Wenn man sich die Funktion anschaut, ist klar was sie tut. Aber seien wir mal kurz naiv: Protokolliert die Funktion etwas mithilfe von SQL in eine Datenbank oder macht sie etwas mit einem SQL-Protokoll welches von der Datenbank produziert wird? Ist es ein Protokoll im Sinne eines Logs oder sind es Protokolldaten von einem Exprimiert oder ähnliches? Okay, zugegeben etwas blöd und vieles lässt sich anhand des Kontextes sicher näher beantworten. Aber ich denke es gibt bessere Namen für so eine solche Funktion, z.B. einfach "DoLog". Das impliziert auch, dass sie etwas tut. Dein Name enthält kein Verb, was mich vermuten lassen würde, wenn ich nur "SQL_Protokoll" sehen würde, dass es sich z.B. um eine Klasse handelt.
    Außerdem zeigt der Name an, dass sie etwas mit SQL tut. Wo steht, dass sie ggf. auch noch eine Datei verändert oder MessageBoxen anzeigt? Gar nicht.

    4) pint_Typ As Integer und Co: Sieht für mich nach ein paar Konstanten aus, die du im Quelltext hast. Eventuell ist ein Enum hier sinnvoller. Wie wichtig ist die Information, dass es sich um einen Übergabeparameter handelt. Es ist keien Referenz als kein wirklicher Unterschied zu einer normalen lokalen Variable. Wie wichtig ist die Information, dass es sich um einen Integer handelt? Wirklich so wichtig, dass ich es immer wissen muss, wenn ich die Variable sehe oder schreiben will?

    5) Optional pstr_Modul As String = "--default--": Als Defaultwerte würde ich hier null (bzw. Nothing) oder einen Leerstring bevorzugen. Die wären bei späteren Abfragen von der Datenbank eventuell auch einfach zu handeln. Natürlich macht das vom Aufwand keinen Unterschied, aber Null, 0, -1, "" sind typische Unterlassungswerte die immer wieder vorkommen und sind leichter zu merken, als --default-- was wohl nur in deinem Programm vorkommt.

    6) Dim ole_CON As New OleDbConnection: Wie wäre es mit Dim connection As New OleDbConnection? Warum ist wichtig zu wissen, dass es eine OleDB-Verbindung ist? CON ist natürlich kurz (Faulheit?), verstößt aber gegen die .NET naming convention und für mich ist connection sprechender.

    7) SYSVAR_DBCon: Globale Variablen... oder ist es gar nicht global, weil sie kein "g" als Präfix hat? Warum ist der Präfix hier groß geschrieben? Viele sind der Meinung, dass man globale Variablen vermeiden soll wo es nur geht.
    Und vom Namen her kommt man auch schnell auf den Gedanken, dass es eine Art Connection-Objekt ist, sonst hättest du ja ein "str" im Präfix, richtig?... oder ist das die Ausnahme der Ausnahme bei Systemvariablen?

    8) ole_CMD.CommandText = ...: Besser wäre wohl Prepared Statement und so. Google mal etwas zum Thema SQL-Injection.

    9) Wo zum Teufel ist der Kommentarblock der Sub?


    kurzda schrieb:

    Wie unterscheiden sich dann Variablen von Methoden und umgekehrt?
    Vom Namen her? Ich mache das z.B. so: Methoden CamelCase (+ Verb im Namen), Variablen lowerCamelCase


    Wichtig ist, dass man sich der Bedeutung und der Vor-/Nachteile bewusst ist und seinen Stil auch konsequent durchzieht. Und stets die Dinge in Frage stellt ;)
    Hey,
    danke für die Rückmeldung.

    Also was der Unterschied von Sub und Functions ist, ist mir klar, was ich damit sagen wollte, wenn Methoden ähnliche Namen wie Variablen haben, woran unterscheiden die sich dann noch (vom Namen her).

    @shaebich nach meinem Empfinden vereinfachen diese Konventionen aber die Lesbarkeit nicht, wenn ich zusätzlichen Aufwand betreiben muss um bspw. den Datentypen zu erkennen und so z.B. Fehlerquellen im Code zu finden.

    Egal, ich muss damit leben, dass ich OldSchool gelernt habe und intuitiv anwende. Es misfällt mir zwar, aber ich muss es übernehmen, denn ich schreibe in VB.Net meine Projektarbeit und meine Projektpartner lernen erst jetzt VB.Net. Also Vogel friß oder stirb.

    Trotzdem Danke für die Eindrücke

    kurzda schrieb:

    @shaebich nach meinem Empfinden vereinfachen diese Konventionen aber die Lesbarkeit nicht, wenn ich zusätzlichen Aufwand betreiben muss um bspw. den Datentypen zu erkennen und so z.B. Fehlerquellen im Code zu finden.


    Bei Konventionen geht es eher darum mehreren Entwicklern die selben Grundlagen zu geben.

    Stell dir vor jeder Ingenieur bei VW baut sein Auto wie er Lust hat, wie soll da der nächsten wissen was der Vorgänger getan hat?!

    kurzda schrieb:


    Egal, ich muss damit leben, dass ich OldSchool gelernt habe und intuitiv anwende. Es misfällt mir zwar, aber ich muss es übernehmen, denn ich schreibe in VB.Net meine Projektarbeit und meine Projektpartner lernen erst jetzt VB.Net. Also Vogel friß oder stirb.

    Trotzdem Danke für die Eindrücke


    Glaub mir, gewöhn dir direkt eine saubere stukturierte Arbeitsweise an wenn du später in die Richtung entwicklung möchtest. Ich selbst habe den Fehler gemacht und sich später an neues zu gewöhnen kann wirklich schwer sein, gerade wenn man in einem Team arbeitet :D
    Diese Frage(n) habe ich mir anfangs auch oft gestellt. Ich bin für mich persönlich zu folgender Lösung gekommen:

    - Im Allgemeinen ist es hilfreich, sich an den Konventionen des Produkts zu orientieren, das du am häufigsten verwendest. Ob das VB.NET, JavaScript oder Brainfuck ist ist egal. Jedenfalls vereinfacht es die Kommunikation mit Gleichgesinnten enorm, wenn alle etwa dieselben Regeln beachten und nicht eigenmächtig irgendwas dazudichten. Ich bin eher in der .NET- und Win32-Welt aktiv, also entspricht mein Stil dem, den ich ständig im MSDN lese (der auch in Post 3 verlinkt ist). Schwierig wird es, wenn du die Konventionen eines fremden Produkts auf ein neues übertragen willst - da kommt wieder der erste Satz ins Spiel.

    - Wenn du ein Projekt privat programmierst, sind Konventionen hilfreich, wenn du dein Programm irgendwann mal erweitern möchtest und z.B. nach 2 Jahren deinen eigenen Code lesen musst (das kommt häufiger vor als man vielleicht denken mag!). Bedenke aber, dass sich dein Stil und deine Vorlieben mit der Zeit ändern werden, vielleicht weil du ein Dokument zu Konventionen gelesen hast / gut findest oder einfach was anderes besser findest. Letztlich kannst du hier aber machen, was du willst.

    - Wenn du ein Projekt für eine Firma (oder in der Uni) neu schreibst oder erweiterst, bekommst du oft Vorgaben zum Programmierstil. Das sind die Vorlieben von anderen Leuten, die du gut finden kannst oder eben nicht. Akzeptieren musst du sie trotzdem - stelle also deine IDE einfach darauf ein, erledige das Projekt und stell die IDE dann wieder zurück. Soll heißen: Wenn dir jemand Vorgaben macht, halte dich dran, diskutiere nur wenn du gefragt wirst und konfiguriere die Auto-Formatierung entsprechend. Das nächste Projekt wird wieder andere Vorgaben haben, also ist jede Beschäftigung damit eher Zeitverschwendung. Natürlich kannst du in der kollegialen Diskussionsrunde deine Vorschläge anbringen - ob denen Rechnung getragen wird, darüber entscheidet aber der Projektleiter.

    Meine Meinung zu deinem Stil:

    - p... kann z.B. auch "Pointer" heißen - die Meinungen darüber gehen natürlich auseinander. Ich persönlich schreibe Typpräfixe nur in unverwaltetem Code (vgl. Win32-API-Deklararionen, z.B. Parameter in msdn.microsoft.com/en-us/libra…s682425%28v=vs.85%29.aspx).
    - Viele C++-Programme verwenden m_ als Präfix für private Variablen in Klassen; soll heißen: Präfixe sind nicht per se schlecht.
    - Wenn eine deiner Methoden so groß / lang wird, dass du dir den Typ der lokalen Variablen nicht mehr merken kannst, hast du m.E. bei der Stukturierung deines Codes was falsch gemacht.

    Sofern du irgendwann mal das Thema Reverse Engineering anschneidest, wirst du merken, dass Namen nur Schall und Rauch sind. In diesem Zusammenhang bist du dann froh, wenn du überhaupt mal Namen findest.
    Gruß
    hal2000

    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „hal2000“ ()