Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Procedurbezeichnung (https://www.delphipraxis.net/163096-procedurbezeichnung.html)

bernau 15. Sep 2011 13:04

Procedurbezeichnung
 
Keine weltbewegende Frage. Aber ich sitze seit eine viertel Stunde vor einem gaaanz trivialen Problem. Wie schreibe ich schönen Code! :-D


Ich habe in einer Klasse folgende Funktion:

Code:
function WorkFile:string;
Manchmal benötige ich im Programm den kompletten Pfad inkl. Datei. Manchmal nur die Datei und manchmal nur den Pfad. Kein Problem mit ExtractFilePath und ExtractFileName. Aber diese Funktionen könnte ich wegen der besseren Lesbarkeit wegrationalisieren und müsste eigendlich nur zwei Funktionen zufügen. Aber wie benenne ich die? Irgendwie fallen mir nur besonders blöde Namen ein.

Code:
function WorkFile:string; // Gibt den kompletten Pfad inkl. Dateiname zurück. Sollte so bleiben, weil immer schon so war.
function WorkFileDir:string; // Gibt nur den Pfad zurück.
function WorkFileFile:string; // Gibt nur den Dateinamen zurück.
WorkFileFile hört sich irgendwie komisch an. Mir fällt aber nichts anderes ein.

Oder sollte ich alles in eine Funktion auslagern

Code:
function WorkFile(aReturnPath:boolean=true;aReturnFilename:boolean=true):string;
Wie gesagt: Tivial. Aber es beschäftigt. Habe ja sonst auch nichts anderes zu tun :evil:

Was meint Ihr?

DeddyH 15. Sep 2011 13:08

AW: Procedurbezeichnung
 
Wie wäre denn so etwas?
Delphi-Quellcode:
type
  TWorkfileType = (wfFull, wfPath, wfFile);
 
function WorkFile(ReturnType: TWorkfileType = wfFull): string;

Luckie 15. Sep 2011 13:10

AW: Procedurbezeichnung
 
Was macht denn die Funktion WorkFile? Wie du siehst, muss ich frage, also schon ein schlechter Funktionsname. Und ist das in einer Klasse gekapselt? Wenn ja, sagt deren Name ja schon aus um was es geht, so dass FilePath und Filename schon aussagekräftig genug sind. (File könnte dann Datei mit Pfad sein.)

Jumpy 15. Sep 2011 13:19

AW: Procedurbezeichnung
 
Ich würde zunächst auch statt WorkFile eher WorkFileName vorschlagen, denn die Funktion liefert ja kein File sondern einen Namen. Wir haben in einer Bibliothek mal eine Klasse TDatei gehabt die hatte dann die Propertys:

Fullname, Name und Dir oder Path, weiß ich gerad nicht mehr.

bernau 15. Sep 2011 13:30

AW: Procedurbezeichnung
 
@Luckie: Workfile (Arbeitsdatei) ist die Datei, die grade bearbeitet wird und ist eine Funktion innerhalb einer Klasse.

@Jumpy: Hast recht. WorkFileName wäre eigendlich besser.

@DeddyH: An eine Aufzählung habe ich auch schon gedacht. Dann wieder verworfen. Denke aber, das ist die besste Lösung. Wäre interessant zu wissen, ob so ein Type schon irgendwo definiert ist.

r2c2 15. Sep 2011 14:03

AW: Procedurbezeichnung
 
Mit der Benennung stimmt da so einiges nicht. "WorkFile" heißt "ArbeiteDatei". Das ist unverständlich. Wenn du "Arbeitsdatei" ausdrücken wolltest. so wäre das WorkingFile oder (mehr oder weniger) CurrentFile. Aber auch das ist nichts für eine Funktion. Eine Funktion sollte i.d.R. ein Verb im Namen haben, denn sie ist nichts, sondern tut etwas. Und das mit File und FileName wurde ja schon gesagt. Also wenn dann getWorkingFileName oder getCurrentFileName.

Boolean-Parameter halte ich für eine ganz schlechte Idee. Die Dinger sind Kontrollkopplunten und zudem schlecht lesbar. Siehe hier: http://www.christian-rehn.de/2011/09...sie-vermeiden/ und hier: http://martinfowler.com/bliki/FlagArgument.html

Auch enum-Parameter halte ich nicht für gut. Das sind nämlich immer noch Kontrollkopplungen und zeugen davon, dass die Funktion etwas tut, was eigentlich nicht ihre Aufgabe ist. ==> SingeResponsibilityPrinciple

Ich würde deshalb immer, wenn cih mit Datennamen arbeite den kompletten Pfad zurück geben und ggf. ExtraxtFileXY anwenden. Wenn du das immer so tust, ist auch immer klar, was passiert. Wenn es Ausnahmen gibt (was giobt die Funktion nochmal zurück?) entstehen unnötige Leichtsinnsfehler.

mfg

Christian

Luckie 15. Sep 2011 14:36

AW: Procedurbezeichnung
 
Und wie heißt die Klasse? Wie wäre es mit CurrentFilename und CurrentFilePath als Bezeichnungen für die Properties? Und wenn die dahinter liegende Methode sicherstellt, dass CurrentFilePath sicherstellt, dass der Pfad mit einem Backslash endet, dann kann man das ganze ohne Probleme zusammensetzen.

bernau 15. Sep 2011 15:28

AW: Procedurbezeichnung
 
Zitat:

Zitat von r2c2 (Beitrag 1124580)
Mit der Benennung stimmt da so einiges nicht. "WorkFile" heißt "ArbeiteDatei". Das ist unverständlich. Wenn du "Arbeitsdatei" ausdrücken wolltest.

Na ja. Man sagt ja auch Workflow. Und das heist ja auch nicht "ArbeiteAblauf" sondern "ArbeitsAblauf". :twisted:


Zitat:

Zitat von r2c2 (Beitrag 1124580)
Eine Funktion sollte i.d.R. ein Verb im Namen haben, denn sie ist nichts, sondern tut etwas. Und das mit File und FileName wurde ja schon gesagt. Also wenn dann getWorkingFileName oder getCurrentFileName.

Dann müsste ja jede Function ein "Get" im Namen beinhalten, weil Sie ja immer etwas macht und zurückgibt. Ein WorkingFilename finde ich leserlicher als GetWorkingFilename.

Es gibt auch Funktionen, die geben einfach einen Zustand zurück. Da schreibe ich doch eher "IsHot" als "GetIsHot". Da ist nichts mit Verb.

Zitat:

Zitat von r2c2 (Beitrag 1124580)
Boolean-Parameter halte ich für eine ganz schlechte Idee. Die Dinger sind Kontrollkopplunten und zudem schlecht lesbar. Siehe hier: http://www.christian-rehn.de/2011/09...sie-vermeiden/ und hier: http://martinfowler.com/bliki/FlagArgument.html

Hast mich überzeugt.


Zitat:

Zitat von r2c2 (Beitrag 1124580)
Auch enum-Parameter halte ich nicht für gut. Das sind nämlich immer noch Kontrollkopplungen und zeugen davon, dass die Funktion etwas tut, was eigentlich nicht ihre Aufgabe ist. ==> SingeResponsibilityPrinciple

Warum sollte es nicht Aufgabe der Funktion sein, eine Rückgabeeigenschaft auszuwerten.


Zitat:

Zitat von r2c2 (Beitrag 1124580)
Ich würde deshalb immer, wenn cih mit Datennamen arbeite den kompletten Pfad zurück geben und ggf. ExtraxtFileXY anwenden. Wenn du das immer so tust, ist auch immer klar, was passiert. Wenn es Ausnahmen gibt (was giobt die Funktion nochmal zurück?) entstehen unnötige Leichtsinnsfehler.


Auch das sehe ich anders. Wenn ich oft Funktionen verschachteln muss, dann mache ich daraus eine neue Funktion. Was kann man besser lesen.
Code:
result:=comparetext(ExtractFileDir(WorkingFileName),ExtractFileDir(EineAndereDatei))=0;

result:=comparetext(WorkingFileDir,EineAndereDateiDir)=0;
Ich finde, das Zweite Beispiel ist besser zu lesen.

Luckie 15. Sep 2011 15:37

AW: Procedurbezeichnung
 
Meinen Beitrag hast du gelesen?

bernau 15. Sep 2011 15:43

AW: Procedurbezeichnung
 
Zitat:

Zitat von Luckie (Beitrag 1124590)
Und wie heißt die Klasse?

OK, jetzt muss ich etwas ausholen ;-)

Die Klasse nennt sich "TccParamStr". Die Klasse kapselt Funktionen um die Komandozeilenparameter (gelesen mit ParamStr(x)) besser auswerten zu können.

Komoandozeilenparameter gibt es in der Regel in drei verschieden Arten. (Bei mir zumindest.)

1) Parameter ohne Wert: z.B. "debug" oder "ShowError"

2) Parameter mit Wert: z.B. "Value=1"

3) Dateinamen. (z.B. weil über den Explorer eine Datei auf die EXE gezogen wurde)

Die Parameter können in einer beliebigen Reihenfolge erscheinen.

Wenn ein Dateiname übergeben wurde, dann ist das in der Regel die Datei die bearbeitet werden soll. Deshalb der Name "WorkFile". (Jetzt WorkingFileName ;-) )

D.h. die Funktion sucht aus allen übergebenen Parametern den heraus, der einen Dateinamen beinhaltet. Der wird in "WorkingFileName" zurück gegeben.

bernau 15. Sep 2011 15:44

AW: Procedurbezeichnung
 
Zitat:

Zitat von Luckie (Beitrag 1124621)
Meinen Beitrag hast du gelesen?

Hey, ich bin ein alter Mann. Ich bin nicht so schnell ;-)

CurrentFilename und CurrentFilePath ist OK, aber auch die muss man zusammensetzen. DAnn finde ich eine weitere Funktion CurrentFileFullPath besser

Luckie 15. Sep 2011 15:47

AW: Procedurbezeichnung
 
Spar dir das Working. Oder gibt es noch Dateinamen, die nicht bearbeitet werden? ;) Es kann doch immer nur eine Datei geben.

bernau 15. Sep 2011 15:50

AW: Procedurbezeichnung
 
Nur "Filename" ist mir zu pauschal. Könnte ja auch die Datei gemeint sein, die sich in ParamStr(0) befindet ;-)

r2c2 15. Sep 2011 15:52

AW: Procedurbezeichnung
 
Zitat:

Zitat von bernau (Beitrag 1124617)
Zitat:

Zitat von r2c2 (Beitrag 1124580)
Mit der Benennung stimmt da so einiges nicht. "WorkFile" heißt "ArbeiteDatei". Das ist unverständlich. Wenn du "Arbeitsdatei" ausdrücken wolltest.

Na ja. Man sagt ja auch Workflow. Und das heist ja auch nicht "ArbeiteAblauf" sondern "ArbeitsAblauf". :twisted:

Sry, aber Workflow ist ein feststehender Begriff.

Zitat:

Zitat:

Zitat von r2c2 (Beitrag 1124580)
Eine Funktion sollte i.d.R. ein Verb im Namen haben, denn sie ist nichts, sondern tut etwas. Und das mit File und FileName wurde ja schon gesagt. Also wenn dann getWorkingFileName oder getCurrentFileName.

Dann müsste ja jede Function ein "Get" im Namen beinhalten, weil Sie ja immer etwas macht und zurückgibt. Ein WorkingFilename finde ich leserlicher als GetWorkingFilename.
Dann lies mal, was Luckie geschrieben hat. Über ne Property kriegst du genau diesen Bezeichner. Properties sind nämlich i.d.R. Substantive.

Zitat:

Es gibt auch Funktionen, die geben einfach einen Zustand zurück. Da schreibe ich doch eher "IsHot" als "GetIsHot". Da ist nichts mit Verb.
Also ich weiß ja nicht, wo du Grammatik gelernt hast, aber bei mir ist "is" definitiv ein Verb. 3. Person Singular. Präsens Aktiv von "to be".

Zitat:

Zitat:

Zitat von r2c2 (Beitrag 1124580)
Auch enum-Parameter halte ich nicht für gut. Das sind nämlich immer noch Kontrollkopplungen und zeugen davon, dass die Funktion etwas tut, was eigentlich nicht ihre Aufgabe ist. ==> SingeResponsibilityPrinciple

Warum sollte es nicht Aufgabe der Funktion sein, eine Rückgabeeigenschaft auszuwerten.
Ich gebe zu, dass das hier ein Grenzfall ist. Der Punkt ist jedenfalls, dass es ein Warnsignal ist, wenn Probleme hast, einen sinnvollen Namen zu vergeben.

Zitat:

Zitat von r2c2 (Beitrag 1124580)
Auch das sehe ich anders. Wenn ich oft Funktionen verschachteln muss, dann mache ich daraus eine neue Funktion. Was kann man besser lesen.
Code:
result:=comparetext(ExtractFileDir(WorkingFileName),ExtractFileDir(EineAndereDatei))=0;

result:=comparetext(WorkingFileDir,EineAndereDateiDir)=0;
Ich finde, das Zweite Beispiel ist besser zu lesen.

Deshalb verwendet man Variablen um Werte mit passenden Namen zwischen zu speichern.

mfg

Christian

Jumpy 15. Sep 2011 16:00

AW: Procedurbezeichnung
 
Also alle Meinungen über einen Kamm geschoren mental zusammenfassend, würde ich glaube ich der Klasse die Funktion als private und mit get im Namen spendieren und die Ergebnisse als nur lesbare Properties (Name dann ohne Get) nach aussen geben. Von aussen sieht das dann ja wie eine Variable aus (zumindest in Sprachen, wo hinter Funktionen immer noch ein () gehört).

Luckie 15. Sep 2011 16:01

AW: Procedurbezeichnung
 
Zitat:

Zitat von bernau (Beitrag 1124633)
Nur "Filename" ist mir zu pauschal. Könnte ja auch die Datei gemeint sein, die sich in ParamStr(0) befindet ;-)

Aber der Parameter wird ja nicht so in der Klasse rumfliegen als Property oder? Und wenn doch, dann würde ich die Bezeichnung ParamFilename wählen.

p80286 15. Sep 2011 16:10

AW: Procedurbezeichnung
 
Zitat:

Zitat von Jumpy (Beitrag 1124640)
Also alle Meinungen über einen Kamm geschoren mental zusammenfassend, würde ich glaube ich der Klasse die Funktion als private und mit get im Namen spendieren und die Ergebnisse als nur lesbare Properties (Name dann ohne Get) nach aussen geben. Von aussen sieht das dann ja wie eine Variable aus (zumindest in Sprachen, wo hinter Funktionen immer noch ein () gehört).

Das ist ja eigentlich nicht der Sinn der Sache, auch wenn eine "sprechende" Schnittstelle nicht zu verachten ist.
Wesentlicher ist ja eigentlich, daß der vollständige Sourcecode leicht lesbar und verständlich ist.

Gruß
K-H

bernau 15. Sep 2011 16:11

AW: Procedurbezeichnung
 
Zitat:

Zitat von r2c2 (Beitrag 1124635)
Sry, aber Workflow ist ein feststehender Begriff.

<scherz an>Wenn ich oft genug WorkFile schreibe, dann ist es bald auch ein feststehender Begriff<scherz aus>

Zitat:

Zitat von r2c2 (Beitrag 1124580)
Dann lies mal, was Luckie geschrieben hat. Über ne Property kriegst du genau diesen Bezeichner. Properties sind nämlich i.d.R. Substantive.

OK, ich könnte ein Nur-Lese-Property verwenden statt einer Funktion.

Zitat:

Zitat von r2c2 (Beitrag 1124580)
Also ich weiß ja nicht, wo du Grammatik gelernt hast, aber bei mir ist "is" definitiv ein Verb. 3. Person Singular. Präsens Aktiv von "to be".

:oops: Ähm... Ich werde mich bei meiner Schule beschweren.

Zitat:

Zitat von r2c2 (Beitrag 1124580)
Zitat:

Auch das sehe ich anders. Wenn ich oft Funktionen verschachteln muss, dann mache ich daraus eine neue Funktion. Was kann man besser lesen.
Code:
result:=comparetext(ExtractFileDir(WorkingFileName),ExtractFileDir(EineAndereDatei))=0;

result:=comparetext(WorkingFileDir,EineAndereDateiDir)=0;
Ich finde, das Zweite Beispiel ist besser zu lesen.
Deshalb verwendet man Variablen um Werte mit passenden Namen zwischen zu speichern.

Du findest also folgendes besser zu lesen?

Code:
  lWorkingFileDir:=ExtractFileDir(WorkingFileName);
  lEineAndereDateiDir:=ExtractFileDir(EineAndereDatei);
  result:=comparetext(lWorkingFileDir,lEineAndereDateiDir)=0;
(Kratz am Kopf)

p80286 15. Sep 2011 16:18

AW: Procedurbezeichnung
 
Delphi-Quellcode:
  Arbeitsverzeichnis:=ExtractFileDir(WorkingFileName);
  Vergleichsverzeichnis:=ExtractFileDir(EineAndereDatei);
  result:=comparetext(Arbeitsverzeichnis,Vergleichsverzeichnis)=0;
Delphi-Quellcode:
  CurrentDirectory:=ExtractFileDir(WorkingFileName);
  DefinedDirectory:=ExtractFileDir(EineAndereDatei);
  result:=comparetext(CurrentDirectory,DefinedDirectory)=0;
No soo schlimm ist das auch nicht.

Gruß
K-H

bernau 15. Sep 2011 16:19

AW: Procedurbezeichnung
 
Zitat:

Zitat von Luckie (Beitrag 1124641)
Zitat:

Zitat von bernau (Beitrag 1124633)
Nur "Filename" ist mir zu pauschal. Könnte ja auch die Datei gemeint sein, die sich in ParamStr(0) befindet ;-)

Aber der Parameter wird ja nicht so in der Klasse rumfliegen als Property oder? Und wenn doch, dann würde ich die Bezeichnung ParamFilename wählen.

ParamFilename ist auch ne Gute Idee.

bernau 15. Sep 2011 16:26

AW: Procedurbezeichnung
 
Zitat:

Zitat von p80286 (Beitrag 1124646)
Delphi-Quellcode:
  Arbeitsverzeichnis:=ExtractFileDir(WorkingFileName);
  Vergleichsverzeichnis:=ExtractFileDir(EineAndereDatei);
  result:=comparetext(Arbeitsverzeichnis,Vergleichsverzeichnis)=0;
Delphi-Quellcode:
  CurrentDirectory:=ExtractFileDir(WorkingFileName);
  DefinedDirectory:=ExtractFileDir(EineAndereDatei);
  result:=comparetext(CurrentDirectory,DefinedDirectory)=0;
No soo schlimm ist das auch nicht.

Gruß
K-H

Es ging darum, daß r2c2 einen "Dreizeiler" einem "Einzeiler" vorzieht.

Wenn schon dann:

Delphi-Quellcode:
  CurrentDirectory:=ExtractFileDir(WorkingFileName);
  DefinedDirectory:=ExtractFileDir(EineAndereDatei);
  result:=comparetext(CurrentDirectory,DefinedDirectory)=0;
Delphi-Quellcode:

   result:=comparetext(WorkingFileDir,EineAndereDateiDir)=0;


Ich finde die zweite Variante, ohne die vorherige zuweisung auf Variablen, besser.

r2c2 15. Sep 2011 17:06

AW: Procedurbezeichnung
 
Zitat:

Zitat von bernau (Beitrag 1124648)
[
Es ging darum, daß r2c2 einen "Dreizeiler" einem "Einzeiler" vorzieht.

Das ist das, was ich auf den Delphi-Tagen versucht hab zu erklären: einfach <> kurz.

Wenn es in meine Code das Prinzip gibt, dass immer und überall der vollständige Pfad verwendet wird, brauche ich nicht zu überlegen, welche der drei möglichen Funktionen ich nun verwenden muss (und werde da auch keine unnötigen Fehler machen). Ich weiß, dass ich immer nur eine Funktion hab und das Ergebnis ist in einem bekannten Format. Möchte ich nun ein anderes Format oder nur einen teil der Information haben, hab ich Funktionen, die das für mich erledigen.

Mein Code wird dadurch länger und langweiliger, ja. Aber ich schreibe Code nur einmal, lese ihn aber viel viel öfter. Somit muss Code leicht zu lesen sein. Ob er irgendwann mal ein paar Sekunden beim Schreiben eingespart hat, ist irrelevant.

Entwickler sträuben sich tendenziell dagegen, "langweiligen" Code zu schreiben Ich will mich da auch gar nicht mal ausnehmen. Auch ich hab die Tendenz. Aber langweiliger Code hilft dabei, Fehler zu vermeiden. Ich mein, das hier ist ein triviales Beispiel, aber, wenn man über den gesamten Code hinweg so arbeitet, vermeidet man tendenziell Fehler, weil man weniger übersieht.

Man darf da gerne anderer Meinung sein, aber ich denke, ich bin mit dieser Position nicht ganz alleine. ;-)


mfg

Christian

bernau 16. Sep 2011 09:06

AW: Procedurbezeichnung
 
Sagen wir mal so, der Einzeiler von meinem Beispiel ist einfacher zu schreiben UND einfacher zu lesen, da am Variablennamen erkenntlich ist, ob es sich um einen Dateinamen, Pfad oder beides handelt.

Aber deine Ansicht ist mir nicht ganz fremd. Ich verwende sehr oft Variablen um Daten zwischenzuspeichern, weil es einfacher zu debuggen ist.
Anstatt in einer Function fünf mal MeineStringlist[aIndex] zu verwenden, weise ich diesen Wert einer Variablen zu und arbeite damit weiter.

Langweiligen Code schreibe ich auch öffters. Ich nehme sehr gerne zusätzliche begin..end um einen Abschnitt in einer Procedure zu kennzeichnen. Ich weis, eine Procedure sollte man so kurz wie möglich halten, manchmal habe ich aber schon über 40 Zeilen in einer Procedure. Dann wirkt das aufteilen mit begin..end ware Wunder.

himitsu 16. Sep 2011 09:13

AW: Procedurbezeichnung
 
comparetext ... Delphi-Referenz durchsuchenAnsiSameText ist da wohl eindeutiger
(es gibt auch Delphi-Referenz durchsuchenSameText, aber das beachtet nicht vollständig die Groß-/Kleinschreibung)

bernau 16. Sep 2011 09:31

AW: Procedurbezeichnung
 
Zitat:

Zitat von himitsu (Beitrag 1124800)
comparetext ... Delphi-Referenz durchsuchenAnsiSameText ist da wohl eindeutiger

Mag sein. Aber: Ich programmiere seit 1995 mit Delphi. Davor mit TurboPascal. Da hat man so seine "bevorzugten" Functionen, weil man die "immer" verwendet hat.

Ja ja. Ich sollte mir öffters mal die RTL anschauen und vieleicht hätte ich die RTL-Session auf den Delphitagen nicht vorher verlassen sollen. Dennoch tue ich mich schwer, jahre lang verwendete Functionen durch "bessere" zu ersetzen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 13:12 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