Delphi-PRAXiS
Seite 1 von 4  1 23     Letzte »    

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Algorithmen, Datenstrukturen und Klassendesign (https://www.delphipraxis.net/78-algorithmen-datenstrukturen-und-klassendesign/)
-   -   Lose Funktionen oder als Funktion in Klasse (https://www.delphipraxis.net/213366-lose-funktionen-oder-als-funktion-klasse.html)

norwegen60 19. Jul 2023 08:48

Lose Funktionen oder als Funktion in Klasse
 
Hallo

ich hätte gerne mal ein aktuelles Feedback, ob es gewichtige Gründe gibt, die dafür/dagegen sprechen, eine Liste von Funktionen besser als lose Funktionen oder besser als Funktionen in einer Klasse zu definieren.

Also so
Delphi-Quellcode:
interface

function HandleWorkflow1: Boolean;
function HandleWorkflow2: Boolean;
function HandleWorkflow3: Boolean;
function HandleWorkflow4: Boolean;

var
  Variable1..3:Integer;

implementation

....
oder so
Delphi-Quellcode:
interface

type
  THandleWorkflow = Class
  private
    FVariable1 : Integer;
    FVariable2 : Integer;
    FVariable3 : Integer;

    procedure GetVariable2: Integer;
    procedure GetVariable3: Integer;
    procedure SetVariable3(const Value: Integer);
  public
    property Variable1 : Integer read FVariable1 write FVariable1;
    property Variable2 : Integer read GetVariable2 write FVariable2;
    property Variable2 : Integer read GetVariable3 write SetVariable3;

    constructor Create;
    destructor Destroy; override;

    function HandleWorkflow1: Boolean;
    function HandleWorkflow2: Boolean;
    function HandleWorkflow3: Boolean;
    function HandleWorkflow4: Boolean;
  end;

implementation

....
Ich habe dazu den Beitrag https://www.delphipraxis.net/46036-lose-funktionen-klassen-kapseln.html gefunden, aber der ist von 2005 und da war OOP noch nicht ganz so genutzt wie heute

Ich sehe folgende Nach- und Vorteile der Klasse

Nachteile der Klasse
- Aufbau ist auf den ersten Blick aufwendiger (z.B. Variablendefinition bestehen aus bis zu 4 Zeilen (FVariable, SetVariable, GetVariable, property Variable)
- Klasse muss Created und Destroyed werden
- Funktionsaufruf etwas länger, da immer auch Classname vorangestellt werden muss (HandlingWorkflow.HandleWorkflow1)


Vorteile der Klasse
+ Über [Ctrl + C] wird Funktionsblock und FVariablen automatisch angelegt (Dadurch ist etwas aufwändigere Aufbau auch kein wirklicher Nachteil)
+ Bei Verwendung von Get/Set kann schön debuggt (oder geloggt) werden, wenn sich eine Variable ändert
+ Eher formalistisch und doch schön: Durch [Ctrl + C] sind Funktionen im Code alphabetisch sortiert angelegt
+ Nach Eingabe des Classname werden automatisch alle verfügbaren Elemente angezeigt

Gibt es andere Vor-/Nachteile?
Gibt es beim späteren Handling in der EXE Vor-/Nachteile? (Resourcenverbrauch, Speed, ...)

Grüße
Gerd

Der schöne Günther 19. Jul 2023 09:09

AW: Lose Funktionen oder als Funktion in Klasse
 
Zitat:

Zitat von norwegen60 (Beitrag 1524692)
Variablendefinition bestehen aus bis zu 4 Zeilen (FVariable, SetVariable, GetVariable, property Variable)

Nein. Warum muss das so sein? Niemand braucht diese Properties. Eine normale Variable tut es auch. Null Mehraufwand.

Zitat:

Zitat von norwegen60 (Beitrag 1524692)
Klasse muss Created und Destroyed werden

Nein. Ist die Methode abhängig von einer individuellen Instanz deiner Klasse? Wenn nicht, dann ist es eine Klassenmethode ("statisch").

Eine Klasse macht das deutlich besser testbar ("Unit-Tests"). Der Code ist austauschbar. Du kannst mehrere unabhängige und sauber getrennte Instanzen (z.B. über mehrere Threads) haben, anstatt das alles mit den selben globalen Variablen jongliert. Objektorientierte Programmierung macht viele moderne Entwicklungsmuster ("Patterns") erst möglich.

Ich würde wirklich noch mal ein Tutorial über OOP lesen, insbesondere die drei Stichworte Datenkapselung, Polymorphie und Vererbung. Zur Datenkapselung gehört insbesondere der von dir erkannte Vorteil, dass die Code Completion (und damit auch der Entwickler) auf den ersten Blick sieht und weiß, was hier thematisch zusammengehört, anders als bei einem Sack von global herumschlabbernden Prozeduren.

himitsu 19. Jul 2023 09:59

AW: Lose Funktionen oder als Funktion in Klasse
 
Jupp, vor allem die Code-Completion ist ein enormer Vorteil.
OK, statt der Variable, bzw. des Klassnamen könnte man auch den Unitnamen dafür verwenden. :stupid:

Ob Variable oder Property scheint erstmal egal zu sein.
Aber Ob
Delphi-Quellcode:
  public
    Variable1 : Integer;
oder
Delphi-Quellcode:
  private
    FVariable1 : Integer;
  public
    property Variable1 : Integer read FVariable1 write FVariable1; // bzw. mit Getter und/oder Setter
Klar, kann man später immernoch aus der Variable ein Property machen, aber wenn man diese Variable z.B. schon irgendwo als Var-Parameter übergeben hat, dann knallt es erstmal.
Ist es schon ein Property, dann lassen sich nahezu immer problemlos auch einfach Getter/Setter nachrüsten.




Eventuell dann noch ein Singleton dafür erstellen.
Wenn als normale Class, dann hat man eine globale Instanz für, so als wären die Funktionen einzeln "direkt" aufrufbar.
Und zusätzlich (falls man sich nichts versperrt (globale Variablen uns so), dann lassen sich z.B. für Threads und Co. auch unabhängige weitere Instanzen erstellen/nutzen.
Delphi-Quellcode:
var
  HandleWorkflow: THandleWorkflow; // globale Variable z.B. im Initialization oder in einem Class-Constructor erstellt
// oder als "function HandleWorkflow: THandleWorkflow;", welches den Singleton liefert


HandleWorkflow.Variable1 := 123;
So wie diese perversen Form-Vaiablen, welche Delphi standardmäßig bereitstellt.



Wenn es "nur" als einzelne Kapselung dienenn soll, dann Class-Function und Class-Property, sowie Class-Var
Delphi-Quellcode:
type
  THandleWorkflow = class
  private class var
    FVariable1 : Integer;
  private
    class procedure SetVariable1(Value: Integer);
  public
    class constructor Create; // wird automatisch aufgerufen, wenn die Unit initialisiert wird
    class destructor Destroy; // wird automatisch aufgerufen, wenn die Unit finalisiert wird
 
    class property Variable1 : Integer read FVariable1 write SetVariable1; // bzw. mit Getter und/oder Setter
end;

THandleWorkflow.Variable1 := 123;
[/DELPHI]

Wobei ich hier inzwischen auch gern mal Records dafür benutze.
Delphi-Quellcode:
type
  THandleWorkflow = record
    ...
    class procedure SetVariable1(Value: Integer); static;
    ...
  end;

Uwe Raabe 19. Jul 2023 10:08

AW: Lose Funktionen oder als Funktion in Klasse
 
Um die globalen Variablen und Funktionen in einer Klasse zu kapseln, ohne davon eine Instanz erzeugen zu müssen, könnte man das so lösen:
Delphi-Quellcode:
type
  TWorkflow = class
  public
  class var
    Variable1: Integer;
    Variable2: Integer;
    Variable3: Integer;
    class function HandleWorkflow1: Boolean;
    class function HandleWorkflow2: Boolean;
    class function HandleWorkflow3: Boolean;
    class function HandleWorkflow4: Boolean;
  end;
Beim Zugriff muss dann immer ein
Delphi-Quellcode:
TWorkFlow.
davor gestellt werden.

Alternativ geht auch ein record:
Delphi-Quellcode:
type
  TWorkflow = record
  class var
    Variable1: Integer;
    Variable2: Integer;
    Variable3: Integer;
    class function HandleWorkflow1: Boolean; static;
    class function HandleWorkflow2: Boolean; static;
    class function HandleWorkflow3: Boolean; static;
    class function HandleWorkflow4: Boolean; static;
  end;
Wenn man dann noch die Redundanz in den Methodennamen (in der Praxis wohl dann auch bei den Variablen) eliminiert, kommt sowas raus:
Delphi-Quellcode:
type
  TWorkflow = record
  class var
    Variable1: Integer;
    Variable2: Integer;
    Variable3: Integer;
    class function Handle1: Boolean; static;
    class function Handle2: Boolean; static;
    class function Handle3: Boolean; static;
    class function Handle4: Boolean; static;
  end;

norwegen60 19. Jul 2023 10:25

AW: Lose Funktionen oder als Funktion in Klasse
 
Hallo zusammen,

da ich in einem Programm/DLL nur eine Instanz der Klasse benötige, habe ich so was perverses wir Delphi gemacht und das noch getoppt


ich habe so was
Delphi-Quellcode:
interface

type
  THandleWorkflow = Class
  private
    FVariable1 : Integer;
    FVariable2 : Integer;
    FVariable3 : Integer;

    procedure GetVariable2: Integer;
    procedure GetVariable3: Integer;
    procedure SetVariable3(const Value: Integer);
  public
    property Variable1 : Integer read FVariable1 write FVariable1;
    property Variable2 : Integer read GetVariable2 write FVariable2;
    property Variable2 : Integer read GetVariable3 write SetVariable3;

    constructor Create;
    destructor Destroy; override;

    function HandleWorkflow1: Boolean;
    function HandleWorkflow2: Boolean;
    function HandleWorkflow3: Boolean;
    function HandleWorkflow4: Boolean;
  end;

var
  HandleWorkflow :THandleWorkflow ;

implementation




initialization

HandleWorkflow := THandleWorkflow .Create;

finalization

HandleWorkflow .Free;

end.

Ich habe nie ganz verstanden, warum das so schlimm ist wenn man sicher nur eine Instanz braucht

Dass ich Variablen nicht als public anlege sondern als property ist zur Gewohnheit geworden

Das
Delphi-Quellcode:
class function HandleWorkflow1: Boolean;
erschließt sich mir nicht ganz. Ich hätte gesagt, dass es letztlich das gleiche ist wie ich es mit initialize und finalization mache

Ich habe jahrelang so eine Klasse wie oben - aber nur mit procedure udn function - ohne Create und Free benutzt. Ohne Probleme.

Grüße
Gerd

Uwe Raabe 19. Jul 2023 10:30

AW: Lose Funktionen oder als Funktion in Klasse
 
Zitat:

Zitat von norwegen60 (Beitrag 1524699)
Ich habe jahrelang so eine Klasse wie oben - aber nur mit procedure udn function - ohne Create und Free benutzt. Ohne Probleme.

Natürlich, und das ist ja auch nicht falsch. Wir zeigen hier lediglich andere Wege auf.

Edelfix 19. Jul 2023 10:53

AW: Lose Funktionen oder als Funktion in Klasse
 
Zu "Über [Ctrl + C] wird Funktionsblock und FVariablen automatisch angelegt" habe ich eine Frage.

Es wird jedes mal eine Set Procedure angelegt. Lässt sich das ausschalten?

DeddyH 19. Jul 2023 11:15

AW: Lose Funktionen oder als Funktion in Klasse
 
Nicht, dass ich wüsste. Aber wenn man etwas mehr tippt:
Delphi-Quellcode:
...
property Blubb: integer read FBlubb write FBlubb;
dann wird auch kein Setter angelegt.

Uwe Raabe 19. Jul 2023 11:28

AW: Lose Funktionen oder als Funktion in Klasse
 
Oder man verwendet das propf Template (oder MMX).

jaenicke 19. Jul 2023 11:39

AW: Lose Funktionen oder als Funktion in Klasse
 
Ein Vorteil der Kapselung in Klassenmethoden ist, dass man sofort sieht, wo eine Methode herkommt. Wenn man also Code kopiert oder den Code restrukturiert, ist es so deutlich einfacher. Hat man nur eine einzelne Methode, die der Compiler nicht findet, ist diese schlechter zu finden.

Natürlich könnte man auch immer den Unitnamen davonschreiben, aber das wäre dann optional. Den Klassennamen kann man hingegen nicht weglassen, womit sichergestellt ist, dass das auch jeder im Team macht.


Alle Zeitangaben in WEZ +1. Es ist jetzt 01:16 Uhr.
Seite 1 von 4  1 23     Letzte »    

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