Delphi-PRAXiS
Seite 2 von 3     12 3      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Methoden-Deklaration vorgeben? (https://www.delphipraxis.net/176115-methoden-deklaration-vorgeben.html)

uligerhardt 13. Aug 2013 14:19

AW: Methoden-Deklaration vorgeben?
 
Zitat:

Zitat von der schöne günther (Beitrag 1224604)
ich hätte die parameterliste gerne nicht ein dutzend mal redundant im quelltext. Hat so etwas eigentlich einen hippen fachbegriff?

dry?

Edit: Ich darf DRY nicht großschreiben. :-/
Edit2: ... oder nur, wenn ich ganze Sätze formuliere. :oops:

Sir Rufo 13. Aug 2013 14:25

AW: Methoden-Deklaration vorgeben?
 
Das kann man auch schön so umsetzen

Delphi-Quellcode:
IMyMethod = interface
  procedure Execute( input1: Integer; input2: TSomeClass; out output: Double );
end;

// Eine Dummy-Klasse zum Veranschaulichen
TMyDummyMethod = class( TInterfacedObject, IMyMethod )
protected
  procedure Execute( input1: Integer; input2: TSomeClass; out output: Double );
end;

procedure TMyMethod.Execute( input1: Integer; input2: TSomeClass; out output: Double );
begin
  output := 0;
end;
Jetzt für jeden konkreten Befehl so eine Klasse erstellen und die jeweilige Instanz in einem
Delphi-Quellcode:
TDictionary<string,IMyMethod>
verwalten

Der Aufruf gestaltet sich ja dann sehr smart
Delphi-Quellcode:
type
  TPacketHandler = class
  private
    fMethodDict : TDictionary<string,IMyMethod>;
  public
    procedure Execute( const ACommandStr : string; input1: Integer; input2: TSomeClass; out output: Double );
    procedure AddMethod( const ACommandStr : string; AMethod : IMyMethod );
  end;

procedure TPacketHandler.Execute( const ACommandStr : string; input1: Integer; input2: TSomeClass; out output: Double );
begin
  fMethodDict[ACommandStr].Execute( input1, input2, output );
end;

procedure TPacketHandler.AddMethod( const ACommandStr : string; AMethod : IMyMethod );
begin
  fMethodDict.AddOrSet( ACommandStr, AMethod );
end;
Man kann das auch mit einem Chain-Of-Responsibility-Pattern lösen, aber für meinen Geschmack nehme ich lieber ein Dictionary :)

Perlsau 13. Aug 2013 14:27

AW: Methoden-Deklaration vorgeben?
 
Zitat:

Zitat von uligerhardt (Beitrag 1224601)
Zitat:

Zitat von Perlsau (Beitrag 1224600)
Dauer der Aktion bei 7 Proceduren: Unter einer Minute!

Mag sein. Eine in die Sprache integrierte Lösung wäre trotzdem schöner, wartungsfreundlicher und weniger fehleranfällig.

Damit mußt du dich an Embarcadero wenden ...

uligerhardt 13. Aug 2013 14:28

AW: Methoden-Deklaration vorgeben?
 
Zitat:

Zitat von Perlsau (Beitrag 1224612)
Damit mußt du dich an Embarcadero wenden ...

Das ist klar. :mrgreen:

Perlsau 13. Aug 2013 14:29

AW: Methoden-Deklaration vorgeben?
 
Zitat:

Zitat von Sir Rufo (Beitrag 1224610)
Das kann man auch schön so umsetzen

Delphi-Quellcode:
IMyMethod = interface
  procedure Execute( input1: Integer; input2: TSomeClass; out output: Double );
end;

// Eine Dummy-Klasse zum Veranschaulichen
TMyDummyMethod = class( TInterfacedObject, IMyMethod )
protected
  procedure Execute( input1: Integer; input2: TSomeClass; out output: Double );
end;

procedure TMyMethod.Execute( input1: Integer; input2: TSomeClass; out output: Double );
begin
  output := 0;
end;
Jetzt für jeden konkreten Befehl so eine Klasse erstellen und die jeweilige Instanz in einem
Delphi-Quellcode:
TDictionary<string,IMyMethod>
verwalten

Der Aufruf gestaltet sich ja dann sehr smart
Delphi-Quellcode:
type
  TPacketHandler = class
  private
    fMethodDict : TDictionary<string,IMyMethod>;
  public
    procedure Execute( const ACommandStr : string; input1: Integer; input2: TSomeClass; out output: Double );
    procedure AddMethod( const ACommandStr : string; AMethod : IMyMethod );
  end;

procedure TPacketHandler.Execute( const ACommandStr : string; input1: Integer; input2: TSomeClass; out output: Double );
begin
  fMethodDict[ACommandStr].Execute( input1, input2, output );
end;

procedure TPacketHandler.AddMethod( const ACommandStr : string; AMethod : IMyMethod );
begin
  fMethodDict.AddOrSet( ACommandStr, AMethod );
end;

Und damit bist du natürlich sehr viel schneller, weil du viel weniger Aufwand betreiben mußt, nicht wahr?

Sir Rufo 13. Aug 2013 19:55

AW: Methoden-Deklaration vorgeben?
 
Zitat:

Zitat von Perlsau (Beitrag 1224614)
Zitat:

Zitat von Sir Rufo (Beitrag 1224610)
Das kann man auch schön so umsetzen

Delphi-Quellcode:
IMyMethod = interface
  procedure Execute( input1: Integer; input2: TSomeClass; out output: Double );
end;

// Eine Dummy-Klasse zum Veranschaulichen
TMyDummyMethod = class( TInterfacedObject, IMyMethod )
protected
  procedure Execute( input1: Integer; input2: TSomeClass; out output: Double );
end;

procedure TMyMethod.Execute( input1: Integer; input2: TSomeClass; out output: Double );
begin
  output := 0;
end;
Jetzt für jeden konkreten Befehl so eine Klasse erstellen und die jeweilige Instanz in einem
Delphi-Quellcode:
TDictionary<string,IMyMethod>
verwalten

Der Aufruf gestaltet sich ja dann sehr smart
Delphi-Quellcode:
type
  TPacketHandler = class
  private
    fMethodDict : TDictionary<string,IMyMethod>;
  public
    procedure Execute( const ACommandStr : string; input1: Integer; input2: TSomeClass; out output: Double );
    procedure AddMethod( const ACommandStr : string; AMethod : IMyMethod );
  end;

procedure TPacketHandler.Execute( const ACommandStr : string; input1: Integer; input2: TSomeClass; out output: Double );
begin
  fMethodDict[ACommandStr].Execute( input1, input2, output );
end;

procedure TPacketHandler.AddMethod( const ACommandStr : string; AMethod : IMyMethod );
begin
  fMethodDict.AddOrSet( ACommandStr, AMethod );
end;

Und damit bist du natürlich sehr viel schneller, weil du viel weniger Aufwand betreiben mußt, nicht wahr?

Nicht unbedingt schneller, aber flexibler ;)

BUG 13. Aug 2013 20:14

AW: Methoden-Deklaration vorgeben?
 
Zitat:

Zitat von Perlsau (Beitrag 1224612)
Zitat:

Zitat von uligerhardt (Beitrag 1224601)
Mag sein. Eine in die Sprache integrierte Lösung wäre trotzdem schöner, wartungsfreundlicher und weniger fehleranfällig.

Damit mußt du dich an Embarcadero wenden ...

Da die Signatur einer Methode mehr oder weniger als Bezeichner verwendet wird, sehe ich kaum eine elegante Methode um das zu lösen.

Mit Makros à la C++ würde es funktionieren:
Code:
#define DECLARE_HANDLER_PROC(NAME) procedure NAME(input1: Integer; input2: TSomeClass; out output: Double)
 
  DECLARE_HANDLER_PROC(proc1);
  DECLARE_HANDLER_PROC(proc2);
  DECLARE_HANDLER_PROC(proc3);
  DECLARE_HANDLER_PROC(proc4);
  DECLARE_HANDLER_PROC(proc5);
Am schönsten fände ich es, wenn man einen vordefinierten Funktions-/Methodentyp bei der Deklaration benutzen könnte.
Das habe ich aber noch in keiner Sprache gesehen.

Furtbichler 13. Aug 2013 20:23

AW: Methoden-Deklaration vorgeben?
 
Zitat:

Zitat von BUG (Beitrag 1224656)
Das habe ich aber noch in keiner Sprache gesehen.

Natürlich nicht, weil man sich damit zum Horstl macht. Man verwendet eine Factory. Deshalb wurden die ja erfunden. Wenn ich in einer Klasse alle Handler/Methoden unterbringe, dann verstoße ich z.B. gegen das Open/Closed-Prinzip und meine Klasse degeneriert immer weiter, d.h. wird immer größer und größer => Ganz ganz schlecht und peinlich.

Also: Mach es wie Sir Rufo vorgeschlagen hat: Nimm eine Factory.

BUG 13. Aug 2013 20:36

AW: Methoden-Deklaration vorgeben?
 
Zitat:

Zitat von Furtbichler (Beitrag 1224657)
Natürlich nicht, weil man sich damit zum Horstl macht. Man verwendet eine Factory. Deshalb wurden die ja erfunden.

Das Problem war imho nicht:
"Wie teile ich Methoden auf Klassen auf." => Factories, usw.
sondern:
"Wie vermeide ich es, tausendmal (auch in verschiedenen Klassen) die gleiche Signatur zu tippen.".

Gerade bei SirRufus' Lösung muss man bei jeder Implementierung von IMyMethod bei jeder Deklaration und jeder Definition der Methode die gleiche Signatur tippen.
Oder übersehe ich da etwas?


BTW: Meine "Lieblingslösung" wurde ja schon im Ausgangspost genannt :oops:

Namenloser 13. Aug 2013 20:37

AW: Methoden-Deklaration vorgeben?
 
@Sir Rufo, Furtbichler: Ändert allerdings auch nichts daran, dass man die Parameterdeklaration bei jeder Methode wieder hinschreiben muss.

Wenn dann würde sich vielleicht eher dieses Pattern anbieten, wo man statt die Parameter einzeln zu übergeben, ein einziges Objekt übergibt, das alle Parameter beinhaltet... mit Namen hab ichs nicht so :-D. So spielt die dann Reihenfolge keine Rolle und man kann auch neue Parameter hinzufügen, ohne alle Methoden anpassen zu müssen.

Also statt:
Delphi-Quellcode:
TMyDummyMethod = class
protected
  procedure Execute( input1: Integer; input2: TSomeClass; out output: Double );
end;

procedure TPacketHandler.Execute( const ACommandStr : string; input1: Integer; input2: TSomeClass; out output: Double );
begin
  fMethodDict[ACommandStr].Execute( input1, input2, output );
end;
Delphi-Quellcode:
TMyMethodParameters = class
  input1: Integer;
  input2: TSomeClass;
  output: Double;
end;

TMyDummyMethod = class
protected
  procedure Execute(parameters: TMyMethodParameters);
end;

procedure TPacketHandler.Execute( const ACommandStr : string; input1: Integer; input2: TSomeClass; out output: Double );
var
  Parameters: TMyMethodParameters;
begin
  Parameters:= TMyMethodParameters.Create(input2, input2, output);
  fMethodDict[ACommandStr].Execute(Arguments);
  Parameters.Free;
end;
(jaja public Felder sind pöhse usw., ist nur qualitativ).

Aber KISS.


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:50 Uhr.
Seite 2 von 3     12 3      

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz