Du bist nicht angemeldet.

mikeb69

Registrierter Benutzer

  • »mikeb69« ist männlich
  • »mikeb69« ist der Autor dieses Themas

Beiträge: 3 800

Dabei seit: 21. März 2008

Wohnort: Neusäß/Bayern

Hilfreich-Bewertungen: 157

  • Private Nachricht senden

1

Dienstag, 9. Dezember 2008, 19:53

Beispiele für guten und schlechten Code (Stil)

Hallo,

ich werde in diesem Beitrag versuchen eine Idee von gutem Code (Stil) zu vermitteln.
Dafür werde ich das ganze - immer wenn es einen Anlass dazu gibt - erweitern.

Das ganze ist natürlich, wie die meisten Dinge subjektiv.
Dennoch glaube ich, einigen von euch einen Anstoss geben zu können.

Da ich aktuelle Codes aus dem Forum verwenden werde, bitte ich euch - falls Ihr einen eurer Codes findet - das nicht persönlich zu nehmen.

1. Verwende möglichst keine festen Zahlen, wenn es dafür eine Konstante gibt:
In vielen Fällen gibt es im Framework Konstanten (Enums) deren Text mehr aussagt als die nackte Zahl, die sich dahinter verbirgt.

Beispiel:

Visual Basic Quellcode

1
2
3
If GetAsyncKeyState(13) Then 
    ....
End If

Der informierte weiss sicherlich, dass die 13 hier ein Enter Symbolisiert.
Schöner, weil besser lesbar ist aber folgendes

Visual Basic Quellcode

1
2
3
If GetAsyncKeyState(Keys.Return) Then 
    ....
End If


2. Suche von Zeichenfolgen in einem String:
Oft verwenden die Leute Schleifen, wenn ein Teilstring in einem String gesucht werden soll.

Beispiel:

Visual Basic Quellcode

1
2
3
4
5
For x= 1 To Len(txt)
   If Mid(String,"suchlänge")="suchbegriff" Then
      'auszuführennde befehe
   End If
Next x

Hier ist eigentlich alles Furchtbar.
1. Der Code stammt mit ziemlicher Sicherheit aus VB6
2. Es wurde eine Schleife zur Suche von "suchbegriff" verwendet.

So ist es übersichtlicher und kürzer.

Visual Basic Quellcode

1
2
3
If txt.Contains("was auch immer") = True Then
     'ausführende befehle
End If


Vielleicht noch eine kleine Ergänzung.
Wer die Position eines Teilstrings sucht, macht das am besten so.

Visual Basic Quellcode

1
Dim pos As Integer = txt.IndexOf("was auch immer")


3. Beachte immer Deine Datentypen und vermische sie nicht:
Auch wenn es mit den Standardeinstellungen keinen Fehler verursacht, sollten Datentypen nicht wild gemischt werden.
Wenn mal eine Umwandlung von einem in den anderen Datentyp nötig ist, gibt es dafür eigene Funktionen.

Beispiel:

Visual Basic Quellcode

1
2
3
4
5
Dim pos As Integer = Me.ListBox1.IndexFromPoint(e.Location)

If pos = "-1" Then
   ...
End If

Die Variable pos ist hier ganz eindeutig und klar als Integer definiert worden - was auch richtig ist.
Verglichen wird pos aber mit einem String.
Dies verursacht zwar keinen Fehler, sollte jedoch vermieden werden.

So sollte der Beispielcode aussehen.

Visual Basic Quellcode

1
2
3
4
5
Dim pos As Integer = Me.ListBox1.IndexFromPoint(e.Location)

If pos = -1 Then
    ...
End If


4. Verwende Try...Catch Blöcke nur dort, wo unerwartete Fehler auftreten können:
Try ... Catch Blöcke wurden erfunden um unerwartet auftretende Fehler abfangen zu können.
Es macht wenig Sinn Code in Try ... Catch Blöcke zu packen, bei denen nichts unerwartetes Auftreten kann.

Beipiel:

Visual Basic Quellcode

1
2
3
4
5
6
7
8
9
10
11
Try
   If move = True Then
      ListBox1.Items.Remove(eintrag)
      ListBox1.Items.Insert(pos, eintrag)
      move = False
      ListBox1.SelectedIndex = pos
   End If

Catch

End Try

Mit diesem Codeschnippsel sollte demonstriert werden wie Einträge einer Listbox mit der Maus verschoben werden können.
Die Listbox ist in diesem Fall in sich geschlossen und unerwartete Situationen sind nicht zu erwarten.
Unerwartet wäre z.B. eine evtl. Zugriffsverletzung in Verbindung mit Dateien.

Der obige Code kann also genausogut ohne den Try ... Catch Block geschrieben werden.

Visual Basic Quellcode

1
2
3
4
5
6
If move = True Then
   ListBox1.Items.Remove(eintrag)
   ListBox1.Items.Insert(pos, eintrag)
   move = False
   ListBox1.SelectedIndex = pos
End If


5. Verweden von Select Case Blöcken anstatt vieler If Anweisungen:
Oft ist es Sinnvoll Select Case Blöcke anstatt eine ganze Reihe von If Anweisungen zu verwenden.
Dies hat den Vorteil, das es ohne großen aufwand und ohne die Übersichtlichkeit des Codes zu gefährden erweitert werden kann.

Klar ist natürlich auch, dass nicht immer ein Select Case Block verwendet werden kann.
Im folgenden Beispiel jedoch schon.

Visual Basic Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
If SFD.FilterIndex = 0 Then
   SsHot.Save(SFD.FileName, System.Drawing.Imaging.ImageFormat.Png)
   Exit Sub
End If

If SFD.FilterIndex = 1 Then
   SsHot.Save(SFD.FileName, System.Drawing.Imaging.ImageFormat.Bmp)
   Exit Sub
End If

If SFD.FilterIndex = 2 Then
   SsHot.Save(SFD.FileName, System.Drawing.Imaging.ImageFormat.Gif)
   Exit Sub
End If

Dadurch, dass Filterindex immer nur einen Wert annehmen kann - drängt sich hier Select Case einfach auf.
Die mögliche Erweiterbarkeit - z.B. wenn es einen neuen Wert abzufragen gibt - spricht auch dafür.

So würde es als Select Case Block aussehen.

Visual Basic Quellcode

1
2
3
4
5
6
7
8
9
10
11
Select Case SFD.FilterIndex
   Case 0
      SsHot.Save(SFD.FileName, System.Drawing.Imaging.ImageFormat.Png)
   Case 1
      SsHot.Save(SFD.FileName, System.Drawing.Imaging.ImageFormat.Bmp)
   Case 2
      SsHot.Save(SFD.FileName, System.Drawing.Imaging.ImageFormat.Gif)
   Case Else
      'Case Else sollte immer Programmiert werden, um auf ungewünschte 
      'bzw. unerwartete Ereignisse aufmekrsam gemacht werden zu können
End Select


6. Das Using Statement verwenden:
Werden verwendete Klassen nicht mehr gebraucht, sollten diese mit Dispose wieder freigegeben werden,
dies gilt vor allem für nicht verwaltete Resourcen. (z.B COM Objekten oder SQL Verbindungen)
(Damit später der Garbage Collector seine Arbeit tun kann.)
Durch Verwenden des Using Statements braucht man sich um solche Dinge nicht mehr zu kümmern.
Der Kompiler erledigt alle nötigen Aufrufe.

Beipsiel:

Visual Basic Quellcode

1
2
3
4
5
Dim SFD As New SaveFileDialog
SFD.Filter = "PNG-Bilder(*.PNG)|*.png|BMP-Bilder(*.bmp)|*.BMP|GIF-Bilder(*.GIF)|*.gif"
If SFD.ShowDialog = Windows.Forms.DialogResult.OK Then
     ...
End If

Bei verwaltetem Code wie z.b. dem SaveFileDialog hat Using den Vorteil, eine gewisse Übersicht in den Quellcode zu bringen.
Übersichtlicher Code ist besser lesbar, was natürlich sehr wichtig ist.
Deshalb ist es Ratsam auch hier den Using Block zu verwenden.

Visual Basic Quellcode

1
2
3
4
5
6
Using SFD As New SaveFileDialog
   SFD.Filter = "PNG-Bilder(*.PNG)|*.png|BMP-Bilder(*.bmp)|*.BMP|GIF-Bilder(*.GIF)|*.gif"
   If SFD.ShowDialog = Windows.Forms.DialogResult.OK Then
     ...
   End If
End Using


7. Verwende nie bekannte Eigenschaftsnamen als Variablenname:
Visual Basic erlaubt es bekannte Eigenschaftsnamen auch als Variable zu verwenden.
Dies macht den Code äußerst schlecht lesbar.
Jeder verbindet mit Eigenschaften wie z.b. "Text" eine Eigenschaft und keine Variable
Beispiel:

Visual Basic Quellcode

1
2
3
4
5
6
Dim Text As System.Text.StringBuilder = New System.Text.StringBuilder(TextBox1.Text)


For i = 0 To XXX 'For-Schleife
  TextBox1.Text = Text.Remove(0, 3).ToString 'Löscht die ersten 3 Zeichen
Next

was spräche dagegen - hier einen anderen Variablennamen zu verwenden.
Einfach der Übersicht halber.

Visual Basic Quellcode

1
2
3
4
5
6
Dim sb As System.Text.StringBuilder = New System.Text.StringBuilder(TextBox1.Text)


For i = 0 To XXX 'For-Schleife
  TextBox1.Text = sb.Remove(0, 3).ToString 'Löscht die ersten 3 Zeichen
Next

sieht doch schon viel klarer aus - oder ?

Gruss

mikeb69

Dieser Beitrag wurde bereits 7 mal editiert, zuletzt von »mikeb69« (25. Februar 2009, 17:29)


Es haben bereits 7 registrierte Benutzer diesen Beitrag als hilfreich eingestuft.

Benutzer, die diesen Beitrag hilfreich fanden:

Smile, LokHeiko, Janik, ramon1611, teddygun300, PanicFR, Denis_Class

julianibus

Registrierter Benutzer

  • »julianibus« ist männlich

Beiträge: 550

Dabei seit: 18. Oktober 2008

Wohnort: Aschaffenburg

  • Private Nachricht senden

2

Mittwoch, 10. Dezember 2008, 19:10

Und

Visual Basic Quellcode

1
My.Application.DoEvents()


nicht vergessen. :D

vanitas-mundi

Registrierter Benutzer

  • »vanitas-mundi« ist männlich

Beiträge: 720

Dabei seit: 11. August 2008

Hilfreich-Bewertungen: 3

  • Private Nachricht senden

3

Donnerstag, 11. Dezember 2008, 08:39

Ebenfalls grausig finde ich tiefe IF-Verschachtelung:

Visual Basic Quellcode

1
2
3
4
5
6
7
If 1 = 1 Then
  If 2 = 2 Then
    If 3 = 3 Then
      ...
    End If
  End If
End If


Viel besser finde ich folgendes:

Visual Basic Quellcode

1
2
3
4
5
Select Case True
Case 1 = 1
Case 2 = 2
Case 3 = 3
End Select
So liegt Handeln im Moment - der aufflammt und zu Asche brennt

roddy

Registrierter Benutzer

  • »roddy« ist männlich

Beiträge: 596

Dabei seit: 26. März 2008

Hilfreich-Bewertungen: 7

  • Private Nachricht senden

4

Donnerstag, 11. Dezember 2008, 09:22

Ich teile die Ansicht von vanitas-mundi. Jedoch: Wenn schon Code-Beispiele, dann bitte so:

Statt diesem hier:

Visual Basic Quellcode

1
2
3
4
5
6
7
If x = 1 Then
 '...
ElseIf x = 2 Then
 '...
ElseIf x = 3 Then
  '...
End If


Das hier:

Visual Basic Quellcode

1
2
3
4
5
Select Case x
Case 1: '...
Case 2: '...
Case 3: '...
End Select 
Live long and prosper!

kevin89

Super Moderator

  • »kevin89« ist männlich

Beiträge: 3 881

Dabei seit: 16. April 2008

Hilfreich-Bewertungen: 155

  • Private Nachricht senden

5

Freitag, 12. Dezember 2008, 15:31

@ mikeb69:

Es kann hier durchaus zu einem Fehler kommen:

Quellcode

1
2
3
4
5
6
If move = True Then
   ListBox1.Items.Remove(eintrag)
   ListBox1.Items.Insert(pos, eintrag)
   move = False
   ListBox1.SelectedIndex = pos
End If



Zum Beispiel wenn nichts gewählt ist und er versucht, einen leeren Eintrag zu löschen oder wenn die Maustaste an einer Stelle in der Listbox losgelassen
wird, wo nichts ist (also auch keine leeren Einträge), dann versucht er nämlich das Item an Position -1 einzufügen.

Unerwartete Fehler können zudem fast immer auftreten - sogar beim laden einer Textdatei, die zum Beispiel geschützt ist. Daher verwende ich den Try-Catch Block auch an Stellen, an denen man nicht einen Fehler erwartet - User hassen Fehler.

Schlechter Stil ist meiner Meinung nach die Verwendung von Try-Catch, wenn man weiß, dass ein Fehler auftritt.

Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von »kevin89« (27. Dezember 2008, 21:54)


powerprogger

was ist geil und hat einen goldenen Stern?

  • »powerprogger« ist männlich

Beiträge: 1 153

Dabei seit: 29. November 2007

Wohnort: wieder im schönen Oberschwaben...

Frühere Benutzernamen: powerprogger

Hilfreich-Bewertungen: 2

  • Private Nachricht senden

6

Freitag, 19. Dezember 2008, 17:18

Ganz mieß finde ich diejenigen, die in jeder zweiten Funktion eine GoTo Anweisung verbasteln. Absoluter MURKS nenn ich das.
Lass mich ich kann das :thumbup: ! - Ooh, kaputt :rolleyes: .

dognose

Registrierter Benutzer

Beiträge: 190

Dabei seit: 16. April 2007

Wohnort: Deutschland

Hilfreich-Bewertungen: 1

  • Private Nachricht senden

7

Freitag, 9. Januar 2009, 13:07

Zitat

Schlechter Stil ist meiner Meinung nach die Verwendung von Try-Catch, wenn man weiß, dass ein Fehler auftritt.


Ich hoffe ich habe dich nicht falsch verstanden, aber da muss ich entschieden intervenieren :-)

Nimm mal dieses Beispile hier:
Ich "weiss" was für Fehler auftreten (können) finde aber dennoch die Lösung mit try und catch schöner, einfacher, schneller, sauberer:

Visual Basic Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
Dim element As String = "PfadZurDateiAusVorherigenFunktionen"

Try
            My.Computer.FileSystem.DeleteFile(element)
        Catch ex As System.IO.FileNotFoundException
            MsgBox("Datei nicht gefunden")
        Catch ex As ArgumentNullException
            MsgBox("Kein Pfad übergeben")
        Catch ex As AccessViolationException
            MsgBox("Keine Rechte")
        Catch ex As UnauthorizedAccessException
            MsgBox("Datei gerade in Verwendung")
        End Try


Ohne Try Catch wäre da wohl sowas hier nötig, wobei die ganzen funktionen die ich "mal so genannt habe" natürlich auch noch programmiert werden müssten:

Visual Basic Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Dim element As String = "PfadZurDateiAusVorherigenFunktionen"
        If element IsNot Nothing Then
            If existiertDatei(element) Then
                If habIchRechteZumLöschen(element) Then
                    If istloeschbar(element) Then
                        loscheDatei(element)
                    Else
                        MsgBox("Datei gerade in Verwendung")
                    End If
                Else
                    MsgBox("Keine Rechte")
                End If
            Else
                MsgBox("Datei nicht gefunden")
            End If
        Else
            MsgBox("Kein Pfad übergeben")
        End If


grüße,
dognose
EasyShare: 17%

EasyShare
WPF FTW... WTF ;)

huttERic

Registrierter Benutzer

Beiträge: 118

Dabei seit: 8. April 2008

Hilfreich-Bewertungen: 1

  • Private Nachricht senden

8

Freitag, 9. Januar 2009, 14:02

Auch finde ich es gräßlich, Rückgabewerte vom Typ Boolean folgendermaßen zu übergeben: (Es sei nun einmal dahingestellt, ob diese Funktion sinnvoll ist. Falls es ein komplexerer Vergleich ist, der oft gebraucht wird, ist es sinnvoll, diesen in eine Funktion auszulagern, damit der eigentliche Code besser lesbar bleibt)

Visual Basic Quellcode

1
2
3
4
5
6
7
	Private Function xyz() As Boolean
    	If (1 = 1) Then
        	Return True
    	Else
        	Return False
    	End If
	End Function

Dageben ist folgende Möglichkeit wesentlich kürzer und auch besser:

Visual Basic Quellcode

1
2
3
	Private Function xyz() As Boolean
    	Return (1 = 1)
	End Function

Auch muss man nicht immer schreiben

Visual Basic Quellcode

1
If xyz = True

sondern kann einfach

Visual Basic Quellcode

1
If xyz
benutzen. In anderen Programmiersprachen wird das fast immer so gemacht.

bsHobbit

Registrierter Benutzer

Beiträge: 645

Hilfreich-Bewertungen: 1

  • Private Nachricht senden

9

Freitag, 9. Januar 2009, 16:14

Zitat



Quellcode

1
2
3
4
5
6
If move = True Then
ListBox1.Items.Remove(eintrag)
ListBox1.Items.Insert(pos, eintrag)
move = False
ListBox1.SelectedIndex = pos
End If




ich überlese einfach mal :

Visual Basic Quellcode

1
if move = True then

grausamere fehler gibts kaum :p

kevin89

Super Moderator

  • »kevin89« ist männlich

Beiträge: 3 881

Dabei seit: 16. April 2008

Hilfreich-Bewertungen: 155

  • Private Nachricht senden

10

Freitag, 9. Januar 2009, 16:33

xD warum ^^ ist typ boolean und funktioniert super der Code, hier ist If meiner Meinung nach genau das richtige, Case hat hier nichts zu suchen... oder meinst du was anderes?

bsHobbit

Registrierter Benutzer

Beiträge: 645

Hilfreich-Bewertungen: 1

  • Private Nachricht senden

11

Freitag, 9. Januar 2009, 16:37

Ja, also ist typ boolean... if wertet boolean aus... also einfach

Visual Basic Quellcode

1
if move then

huttERic

Registrierter Benutzer

Beiträge: 118

Dabei seit: 8. April 2008

Hilfreich-Bewertungen: 1

  • Private Nachricht senden

12

Freitag, 9. Januar 2009, 23:39

Genau. Bei If kein True oder False reinbringen, sondern kein Boolscher Operand und bei Bedarf einfach die Bedingung mit ! umkehren.
Was ich auch grässlich finde, ist es, wenn man statt MessageBox.Show() einfach nur MsgBox nimmt.
Und am schlimmsten ist es, dass VB automatisch implizit konvertiert. Also folgendermaßen:

Visual Basic Quellcode

1
2
Dim s As Integer
s = "1234"

Was natürlich falsch ist. In C# gäbe das Äquivalent einen Compilerfehler. Also müsste man hier schreiben (angenommen der String "1234" kommt von woanders her):

Visual Basic Quellcode

1
2
Dim s As Integer
s = Convert.ToInt32("1234")

milaim

IT specialist

  • »milaim« ist männlich

Beiträge: 1 605

Dabei seit: 1. April 2008

Wohnort: Nürnberg

Hilfreich-Bewertungen: 41

  • Private Nachricht senden

13

Montag, 12. Januar 2009, 15:28

Variablen verwenden

Statt x mal etwas immer wieder einzugeben, wie hier:

Visual Basic Quellcode

1
2
3
4
5
If File.Exists("C:\test.txt") Then 
File.delete("C:\text.txt") 
Else 
'Irgendwas 
End If


sollte man lieber eine Variable benutzen, die man nur 1 mal ändern muss.



Visual Basic Quellcode

1
2
3
4
5
6
7
Dim strDatei As String = "C:\test.txt" 

If File.Exists(strDatei) Then 
File.delete(strDatei) 
Else 
'Irgendwas 
End If


// EDIT: Oops, hochkomma vergessen.. korrigiert :rolleyes:

// EDIT2: "Then" hinzugeügt.
$result = mysql_query("SELECT finger FROM hand WHERE position=3");
echo $result;

Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von »milaim« (13. Januar 2009, 19:57)


kevin89

Super Moderator

  • »kevin89« ist männlich

Beiträge: 3 881

Dabei seit: 16. April 2008

Hilfreich-Bewertungen: 155

  • Private Nachricht senden

14

Dienstag, 13. Januar 2009, 15:45

@bsHobbit: Ist doch egal, ob man True bzw. False dazuschreibt. Selbes Ergebnis.

bsHobbit

Registrierter Benutzer

Beiträge: 645

Hilfreich-Bewertungen: 1

  • Private Nachricht senden

15

Dienstag, 13. Januar 2009, 16:04

Siehe Titel:
[VB.NET] Beispiele für guten und schlechten Code (Stil)
...
und wenn das mit =True schreibt, dann ist es schlechter Stil!

roddy

Registrierter Benutzer

  • »roddy« ist männlich

Beiträge: 596

Dabei seit: 26. März 2008

Hilfreich-Bewertungen: 7

  • Private Nachricht senden

16

Dienstag, 13. Januar 2009, 16:54

@milaim:

Wenn schon Beispiele bringen, dann syntaktisch richtige (beidesmal fehlt das "Then").
Live long and prosper!

kevin89

Super Moderator

  • »kevin89« ist männlich

Beiträge: 3 881

Dabei seit: 16. April 2008

Hilfreich-Bewertungen: 155

  • Private Nachricht senden

17

Dienstag, 13. Januar 2009, 17:05

Naja mag sein das es ohne True/False kürzer ist aber es ist meiner Meinung nach kein schlechter Stil. Hat finde ich nichts damit zu tun.

dusti

Registrierter Benutzer

  • »dusti« ist männlich

Beiträge: 1 172

Dabei seit: 1. Juni 2007

Wohnort: Hinter dir

  • Private Nachricht senden

18

Dienstag, 13. Januar 2009, 18:27

Es wird aber sogar im MSDN als schlechter Stil bezeichnet. Ob das jetzt aussagekräftig ist, muss aber jeder für sich entscheiden...
Mfg dusti

mikeb69

Registrierter Benutzer

  • »mikeb69« ist männlich
  • »mikeb69« ist der Autor dieses Themas

Beiträge: 3 800

Dabei seit: 21. März 2008

Wohnort: Neusäß/Bayern

Hilfreich-Bewertungen: 157

  • Private Nachricht senden

19

Dienstag, 13. Januar 2009, 19:01

hallo,

Zitat

Naja mag sein das es ohne True/False kürzer ist aber es ist meiner Meinung nach kein schlechter Stil. Hat finde ich nichts damit zu tun.

da muss ich kevin89, mal ausnahmsweise zustimmen.

gruss

mikeb69

ryLIX

Registrierter Benutzer

Beiträge: 330

Dabei seit: 11. Januar 2009

  • Private Nachricht senden

20

Dienstag, 13. Januar 2009, 19:41

Hmm ihr sprecht über Stil ...
Da ich eigentlich aus dem Bereich der Borlandsprachen komme (Delphi, C++) halte ich mich auch in VB an den Styleguide von Delphi.
Ist halt eine Angewohnheit ^^

Hier mal was zum Thema CodingStyle:
StyleGuide

Es gibt auch einen von Microsoft (mich gruselt es schon wenn ich daran denke -.-) den kann aber, soweit ich das gesehen habe, nur als Buch kaufen.
Leider wird dort z.B. die Ungarische Notation nicht so eingesetzt wie es vom Erfinder gedacht war.
Was natürlich einheitliche Standards schwer macht.

Ich selbst verwende die Ungarische Notation nur bei Steuerelementen und dann auchnur die Variante "Systems Hungarian".

Wer gern auch noch lesen möchte:
Borland Styleguide in deutsch

kopieren statt kapieren

Social Bookmarks