AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Tutorials Code Smells
Tutorial durchsuchen
Ansicht
Themen-Optionen

Code Smells

Ein Tutorial von Coffeecoder · begonnen am 5. Mai 2011 · letzter Beitrag vom 11. Jan 2012
Antwort Antwort
Seite 2 von 4     12 34      
Benutzerbild von Coffeecoder
Coffeecoder
Registriert seit: 27. Apr 2011
Hallo DP-Mitglieder,

Ich habe ein kleinen Kurs über das Thema "Code Smells" für euch vorbereitet.
Das Ziel dieses Kurses ist das Verstehen was "Code Smells" sind. Denn jeder Programmierer hat (unbewusst) solche in seinem Code.

Theorie:

Das Wort "Code Smells" was übersetzt "(schlechter) Geruch" heißt,
stammt von Kent Beck und wurde durch das Buch Refactoring von Martin Fowler verbreitet.

Code Smells ist ein schlecht strukturierter Programmcode.
Der Code ist für den oder einen anderen Programmierer schwer zu verstehen.

Bei Verbesserungen oder Erweiterungen kommen neue Fehler dazu.
"Code Smells" wird erst erkannt bei einer Überarbeitung des Programmcodes.


Welche "Code Smells" existieren?

Es gibt eine Unmenge von schlecht-struktierter Programmcode-Beispiele.
Hier einige Beispiele die sich auf die objektorientierte Programmierung (Java, Delphi, ...) beziehen:
  1. Code-Vermehrung: Der identische Code taucht im Programm an mehreren Stellen auf.
  2. Langer Code in Methode: Der Programmcode in einer Funktion, Prozedur ist zu lang.
  3. Lange Parameterliste: einige übergebene Parameter die unnötig sind.
  4. Nichtaussagender Name: Aussagekräftige Name erfüllen das Verständnis des Codes oder Inhalt einer Variable.
  5. Toter Code: Ein Programmcode welches nicht mehr gebraucht wird.
Quelle : http://de.wikipedia.org/wiki/Code_smells

Natürlich gibt es noch mehrere Arten und interessante Bücher die das Thema detaillierter
beschreiben wie z.B das Buch : "Clean Code - Refactoring, Patterns, Testen und Techniken für sauberen Code" von Robert C. Martin.

Beispiele/Tipps:
  1. "Code-Smell"
    Delphi-Quellcode:
    procedure anpassenChart;
    begin
                    with Chart1 do
                    begin
                           Legend.visible := false;
                           View3D := false;
                           Title.Text.Clear;
                           Title.Text.Add('Chart');
                    end;

                    with Chart2 do
                    begin
                           Legend.visible := false;
                           View3D := false;
                           Title.Text.Clear;
                           Title.Text.Add('Chart');
                    end;

                    with Chart3 do
                    begin
                           Legend.visible := false;
                           View3D := false;
                           Title.Text.Clear;
                           Title.Text.Add('Chart');
                    end;
    end;
    Es ist nicht falsch, der Code funktionniert ja. Aber was ist schlecht daran?
    Ganz einfach: Es sollen jetzt doch Legende visible sein. Was macht man?
    Legend.visible := true setzen und Copy-Paste.
    Das ist anfällig für Fehler, einmal nicht aufgepasst und schon ein Legend.visible := false vergessen zu überschreiben.

    So macht man es besser:
    Delphi-Quellcode:
    procedure anpassenChart(ch : TChart);
    Begin
                    with ch do
                    begin
                          Legend.visible := false;
                          View3D := false;
                          Title.Text.Clear;
                          Title.Text.Add('Chart');
                    end;
    end;
    Aufruf:
    Delphi-Quellcode:
    ...
    var i : integer;
    begin
            for i := 1 to 3 do anpassenChart('Chart'+IntToStr(i));
    end;
  2. und
  3. Beide Punkten sind verwandt, denn es geht ja um Methoden (Funktion, Prozedur).
    Hier zeige ich kein Beispiel, aber ein paar Tipps:
    1. Kurze Parameterliste, welche für eine einzige Aufgabe gebraucht werden.
    2. Es sollen nicht mehr als 20 Programmzeilen in einer Methode stehen.
    3. Eine Methode soll nur eine Aufgabe erfüllen. (eine Funktion die den Flächeninhalt eines Kreises berechnet, soll nicht noch den Umfang berechnen, dies sollte in einer separaten Funktion untergebracht werden.)
  4. Ich komme sofort zu einem Beispiel:

    Schlechter Name:

    Delphi-Quellcode:
    var
         d : integer;
    begin
           ...
           if d ...
    end;
    Was will die Variable d uns sagen? Nicht viel!

    Besser:

    Delphi-Quellcode:
    ...
    var
         TageSeitErstellung : integer;

    begin
          ...
          if TageSeitErstellung ....

    end;
    Hier sagt die Variable TageSeitErstellung uns der Zweck dieser Variable aus. Man weiss sofort, der Inhalt ist die Anzahl Tage seit der Erstellung von ...

    Noch ein typisches Beispiel mit dem Typ boolean:

    Delphi-Quellcode:
    var
          Daten : boolean;
    Daten sagt wieder nichts aus. Man kann es so verstehen:
    1. DatenGeLoescht
    2. DatenVorhanden
    3. DatenGesendet
    4. DatenVerarbeitet
    5. DatenKorrupt
    6. ...

  5. Toter Code ist :
    1. Ein auskommentierter Code
    2. Ein Codestück welches immer übersprungen wird. Hier ist die if-Anweisung überflüssig:
      Delphi-Quellcode:
      var
        N : int;

      begin
              N := 0;
              ...
              if N = 3 then
              begin
                   ....
              end;
              ...
      end;

Schlusswort:

Kennt man einige Code-Smells, so kann man diese vermeiden, damit der Programmcode nicht "schlecht riecht".

Ich hoffe ich könnte euch ein bisschen über dieses interessante Thema erzählen.
Bitte um konstruktive Kritik.

Danke bis Bald.

Mfg Coffeecoder
Coffeecoder

Geändert von Coffeecoder ( 6. Mai 2011 um 17:43 Uhr) Grund: Ich wurde gebeten, noch einige Beispiele und Tipps zu den Punkten zu zeigen.
 
Benutzerbild von s.h.a.r.k
s.h.a.r.k
 
#11
  Alt 6. Jul 2011, 22:50
Außerdem habe ich die Erfahrung gemacht das sich die nachfolgenden Variablen schlecht Debugen lassen.
Da Sie wegen Optimierung unterdrückt werden.

PS:
Und Zeilen sparrt man sich dadurch auch nicht wirklich.

gruss
Aber Schreibarbeit
  Mit Zitat antworten Zitat
EWeiss
 
#12
  Alt 6. Jul 2011, 23:01
Außerdem habe ich die Erfahrung gemacht das sich die nachfolgenden Variablen schlecht Debugen lassen.
Da Sie wegen Optimierung unterdrückt werden.

PS:
Und Zeilen sparrt man sich dadurch auch nicht wirklich.

gruss
Aber Schreibarbeit
Ahh jo Copy und Paste ... hehehehe

gruss
  Mit Zitat antworten Zitat
Benutzerbild von Meflin
Meflin
 
#13
  Alt 6. Jul 2011, 23:05
Ahh jo Copy und Paste...
... ist sehr oft ein Zeichen dafür, dass ein Smell vorliegt
Leo S.
  Mit Zitat antworten Zitat
Benutzerbild von Stevie
Stevie

 
Delphi 10.1 Berlin Enterprise
 
#14
  Alt 6. Jul 2011, 23:24
Die "Notwendigkeit" für ein with ist wahrscheinlich Feature Envy, Indecent Exposure und/oder Message Chains
Stefan
  Mit Zitat antworten Zitat
FredlFesl

 
Delphi 2009 Enterprise
 
#15
  Alt 7. Jul 2011, 08:03
Was ist an with so böse?
...Und mitunter kommt der Compiler schon mal durcheinander...
Ganz sicher nicht. Der Compiler ist deterministisch, da der die Grammatik zumindest hier formal korrekt interpretiert.

Die "Notwendigkeit" für ein with ist wahrscheinlich Feature Envy, Indecent Exposure und/oder Message Chains
So hab ich das noch nicht gesehen. Aber stimmt: Verwender des 'WITH' müssen nur ihren Code aufräumen (zur Not mit Class Helper), dann wird das 'WITH' meist überflüssig.

Mein Code riecht immer dann gut, wenn ich keine Kommentare benötige, da der Code flüssig zu lesen ist (wie eine Beschreibung) und einfach zu verstehen ist.
Weiterhin spüre ich, das ich in die richtige Richtung gehe, wenn die Klassen mit Scheuklappen durch die Gegend rennen, d.h. keine Abhängigkeiten zu anderen Klassen existieren. Dann kann ich mit den Klassen vieles anstellen, ohne mir einen abzubrechen.

Eine schöne Beschreibung für eine gut implementierte Methode ist von Dr.Bob: "Wenn Du das, was die Methode macht, beschreibst, und ohne das Wörtchen 'und' auskommst, hast Du etwas richtig gemacht".
  Mit Zitat antworten Zitat
Benutzerbild von Deep-Sea
Deep-Sea

 
Delphi XE2 Professional
 
#16
  Alt 7. Jul 2011, 08:16
Uhu, bricht hier wieder mal ein With-Glaubenskrieg aus? *schon mal das Popcorn hol*
Chris
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

 
Delphi 11 Alexandria
 
#17
  Alt 7. Jul 2011, 08:34
Delphi-Quellcode:
with Popcorn do
  Mampf;
Detlef
  Mit Zitat antworten Zitat
Benutzerbild von Coffeecoder
Coffeecoder

 
Delphi 6 Enterprise
 
#18
  Alt 11. Jan 2012, 07:26
Hey,

Ich danke für eure Feedbacks. Es ist mir klar, dass es schon bisschen her ist.
Hallo Coffeecoder,

gefällt mir ganz gut, fällst bei deinem Beispiel dann über die eigenen Regeln.

ich denke
Delphi-Quellcode:
procedure anpassenChart(ch : TChart);
Begin
end;
hier ist ch auch nicht gerade ein aussagekräftiger Parameter, könnte auch ein Char oder so sein

Gruß
MrOuzo
Das stimmt da falle ich selbst über die "Anti-Code-Smells"-Regeln. Besser soll heissen, wie bereits erwähnt:
Delphi-Quellcode:
procedure anpassenChart(pchart : TChart);
Begin
    ....
end;
Weiter gehts

Außerdem wird hier als Parameter eine Zeichenkette übergeben: anpassenChart('Chart'+IntToStr(i)); laut Deklaration müsste es aber ein Objekt vom Typ TChart sein. Mir ist zwar klar, was du aussagen willst, aber trotzdem sollte es doch ein Beispiel sein, was zumindest compiliert.
Da habe ich wieder nicht aufgepasst

Also ich bedanke mich für eure Hinweise und Vorschläge, ich werde das Tutorial wohl einmal überarbeiten müssen und gebe es als PDF auch frei.

Bis dahin, habt bisschen Geduld
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

 
Delphi 11 Alexandria
 
#19
  Alt 11. Jan 2012, 07:31
Delphi-Quellcode:
procedure anpassenChart(pchart : TChart);
Begin
    ....
end;
Der Präfix P erweckt aber eher den Eindruck, es handle sich um einen Zeiger auf ein TChart. Wieso nicht einfach Chart, AChart oder meinetwegen TheChart?
Detlef
  Mit Zitat antworten Zitat
Benutzerbild von Coffeecoder
Coffeecoder

 
Delphi 6 Enterprise
 
#20
  Alt 11. Jan 2012, 07:41
Delphi-Quellcode:
procedure anpassenChart(pchart : TChart);
Begin
    ....
end;
Der Präfix P erweckt aber eher den Eindruck, es handle sich um einen Zeiger auf ein TChart. Wieso nicht einfach Chart, AChart oder meinetwegen TheChart?
Hmm ok. Ich habe gerade diesen Beitrag hier in der DP gefunden
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 4     12 34      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:09 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz