Delphi-PRAXiS
Seite 1 von 7  1 23     Letzte »    

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Die Delphi-IDE (https://www.delphipraxis.net/62-die-delphi-ide/)
-   -   Interface-Unterstützung (https://www.delphipraxis.net/193733-interface-unterstuetzung.html)

stahli 2. Sep 2017 11:01

Interface-Unterstützung
 
Ich arbeite viel mit Interfaces. Mich nervt, dass die IDE (m.E.) das kaum unterstützt.
So muss man redundant und wiederholt ständig das gleiche schreiben und man findet die Methoden nicht vernünftig in der Unit, da diese beliebig einsortiert werden.

Also folgendes Beispiel mit anschließender Erklärung...


UnitMyIntf.pas

Delphi-Quellcode:
IMyIntf1 = Interfaces
  property MyProp1: string read write;
  procedure Do1(P: string);
end;

IMyIntf2 = Interfaces
  property MyProp2: string read;
  procedure Do2(P: string);
end;
UnitMyClass.pas

Delphi-Quellcode:
TMyClass = class(TInterfacedObject, IMyIntf1, IMyIntf2)
protected { IMyIntf1 }
  fMyProp1: string;
  function _get_MyProp1: string;
  procedure _set_MyProp1(Value: string);
protected { IMyIntf2 }
  fMyProp2: string;
  function _get_MyProp2: string;
public
  constructor Create; virtual;
  destructor Destroy; override;
public { IMyIntf1 }
  property MyProp1: string read _get_MyProp1 write _set_MyProp1;
  procedure Do1(P: string);
public { IMyIntf2 }
  property MyProp2: string read _get_MyProp2;
  procedure Do2(P: string);
end;

...

{ TMyClass }

constructor TMyClass.Create;
begin
end;

destructor TMyClass.Destroy;
begin
  inherited;
end;

{ TMyClass / IMyIntf1 }

function TMyClass._get_MyProp1: string;
begin
  Result := fMyProp1;
end;

procedure TMyClass._set_MyProp1(Value: string);
begin
  fMyProp1 := Value;
end;

procedure TMyClass.Do1(P: string);
begin
end;

{ TMyClass / IMyIntf2 }

function TMyClass._get_MyProp2: string;
begin
  Result := fMyProp2;
end;

procedure TMyClass.Do2(P: string);
begin
end;

Ich hätte gern folgende Aspekte:

1) Im Interface möchte ich die Getter und Setter nicht komplett definieren müssen. Dies würde die Sache vereinfachen und die Übersichtlichkeit erhöhen.
Der Compiler könnte ja eigentlich - wenn dort "read" und/oder "write" steht, einfach "gedanklich" Standardgetter und -setter voraussetzen.

2) In den Klassen hätte ich gern die Abschnitte, die Interfaces zugewiesen sind, entsprechend geordnet und beschrieben.
Im Implementationsteil sollte das entsprechend gehandhabt werden. Zunächst sollten Constructor und Destructor kommen, dann die normalen Methoden und dann die Interface-Methoden mit entsprechender Gliederung und Sortierung.

3) Sofern in den Interfaces Getter und Setter definiert sind und diese in den Klassen erstmalig erzeugt werden, sollten auch gleich private Felder "fMyProp: MyType;" eingerichtet und in den Gettern und Settern benutzt werden. Da ist ja bestimmt zu 95% der Normalfall und mich nervt, dass man das jedesmal neu von Hand machen muss (zumal Getter und Setter ja wild in der Unit verteilt sind).

4) Refactoring von Interfaces zu Klassen sollte möglich sein. Wenn ich z.B.
Delphi-Quellcode:
procedure Do1(P: string);
im Interface ändere in
Delphi-Quellcode:
procedure Do1(const aValue: string);
sollte das auch in die Klassendeklarationen übertragbar sein, die dieses Interface verwenden (im Interface- und Implementationsteil).
Die Methoden können dann zwar ggf. nicht kompiliert werden, aber ich brauch nur noch die logischen Dinge anpassen und bin sicher, dass die Änderungen im Interface (z.B. Propertynamen) auch in den Klassen angepasst wird.


Ich wüsste mal gern Eure Meinung dazu.
Haltet Ihr die Überlegungen für sinnvoll/wichtig?
Gibt es dazu vielleicht schon Möglichkeiten, die ich bisher übersehen habe (Ich würde mich in den A... beißen und davon ein Foto hochladen :stupid:)).

Hättet Ihr (die Ihr mit Interfaces arbeitet) Interesse an so einer Lösung?

Auf Emba setze ich diesbezüglich leider nicht. Wenn diese Dinge demnächst richtig gut unterstützt würden, dann würde ich sogar nochmal ein Update in Erwägung ziehen. Aber da gibt es ja sicher andere Prioritäten.

Aber ich habe eine Idee zu einem Tool, das den Interface-Quelltext analysiert, die fehlenden Getter und Setter (wie oben im Beispiel) ergänzt und dann die verwendenden Klassen zerlegt, ordnet, ergänzt, anhand der Interface-Vorgaben korrigiert und entsprechend dem obigen Beispiel neu zusammenbaut. So könnten viele, immer gleiche Arbeitsschritte deutlich reduziert werden.
(Angefangen habe ich damit schon.)

Meiner Meinung nach kann das extrem viel Arbeit ersparen und gleichzeitig die Übersichtlichkeit deutlich erhöhen.


Was meint Ihr dazu?
Habt Ihr Interesse an solch einem Tool?
Ist das überflüssig?

Gruß
Stahli


PS: Die externe Umsetzung halte ich für mich für machbar (so dass die Units einfach von der Exe geladen und aufbereitet werden). Damit das richtig komfortabel wäre müsste man das durch einen IDE-Experten realisieren, der auch scannen kann, welche Units unter "uses" stehen und diese nach der Interface-Deklaration durchsuchen. Dazu habe ich noch keine Vorstellung, wie das geht...

Aviator 2. Sep 2017 12:23

AW: Interface-Unterstützung
 
Also ich arbeite in letzter Zeit fast ausschließlich mit Interfaces. Alle Punkte die du angesprochen hast, habe ich jetzt nicht direkt verstanden, bin aber auch nur relativ schnell über deinen Post hinweg geflogen.

Zu der Einsortierung in den Quelltext an einer bestimmten Position kann ich sagen, dass ich da früher darauf geachtet habe. Aber heute verwende ich ausschließlich die Methodenliste des CnPacks. Einfach STRG + D, den Anfang des Methodennamens eingeben und Enter. Da interessiert mich im Prinzip nicht mehr wo die Methode wirklich steht. Ich nutze eben sehr viele Tastenkombinationen die mir das Leben in der IDE deutlich vereinfachen und somit auch gewisse Dinge nicht benötigt werden.

Das automatische Anlegen des privaten Feldes und das Ausfüllen der Getter/Setter wäre sicherlich eine schöne Sache. Aber oft mache ich im Getter und Setter noch diverse Abfragen um unnötige Zuweisungen zu vermeiden. Von daher wäre das für mich nur bedingt hilfreich.

Die Properties in der Klasse brauchst du gar nicht mehr anzulegen. Es reicht, einfach nur die Getter und Setter zu erzeugen. Die Properties werden durch das Interface zur Verfügung gestellt. Setzt natürlich voraus, dass du ausschließlich mit Interfaces im Zusammenhang mit der Klasse arbeitest.

Das mal dazu wie ich damit umgehe. Manchmal würde ich mir allerdings wünschen, dass ein STRG + Klick bzw. ein STRG + G zum Springen zur Methode nicht zur Interface-Deklaration sondern zur Klasse die an dieser Stelle instanziiert wird zu springen. Visual Studio macht so etwas. Das schaut sich an, welche Klasse der Interface Variablen zugewiesen wurde und springt dann direkt zur Klasse und nicht zum Interface.

jaenicke 2. Sep 2017 13:08

AW: Interface-Unterstützung
 
Ich kann dir nur Modelmaker Code Explorer empfehlen. Damit kann man viel zu den Punkten umsetzen, die du angesprochen hast.

Die Sortierung der Methoden geht damit zwar, aber da achte ich gar nicht drauf. Die ist mir ziemlich egal.

Zu Punkt 3... Dafür gibt es ja die Klassenvervollständigung. Die legt das automatisch an.

Und die Deklarationen aus einen Interface kann man auch automatisch übernehmen, auch ohne Addon.

stahli 2. Sep 2017 13:46

AW: Interface-Unterstützung
 
Oh, man beachte die zwei letzten Beiträge:
http://www.delphipraxis.net/130219-i...eexplorer.html

Ich hatte MM und MMX völlig verdrängt.
Werde mir jetzt mal die Demos laden.

Scheint ja ganz gut auf meine Wünsche zu passen.
Gute, aktuelle Video-Tutorials (mit sprachlichen Erläuterungen) wären sicher trotzdem sinnvoll (und würden den Verkauf unterstützen) ...


@jaenicke
Trotzdem mal die Frage: Delphi legt Klassenvervollständigung und Methodenübernahme von Interfaces legt ja aber keine privaten Felder an - oder gibt es das doch irgendwie?

himitsu 2. Sep 2017 14:25

AW: Interface-Unterstützung
 
Liste der Anhänge anzeigen (Anzahl: 1)
Interfaces haben eigentlich keine Property, da gibt es nur Methoden, auch wenn Delphi hier die Property mit anbietet.
Aber daher fehlt dafür dann auch die automatische Codeverfolständigung.
Obwohl man sich natürlich fragen könnte, warum für Interfaces nicht einfach die Vervolständigung für Klassen verwendet wird/kopiert wurde. (abzüglich der Methodenimplementation und der Felder)

Private: Private Felder werden angelegt, für Property.
Außer in der Starter, da fehlt eh Vieles.
Delphi-Quellcode:
type
  TMyClass = class
    property Name1: string read GetName1 write SetName1; // Template prop
    property Name2: string read FName2   write FName2;   // Template propf
    property Name3: string read GetName3 write SetName3; // Template propgs
    property Name4: string read GetName4; // Template propro
    property Name5: string read FName5;   // Template proprof
    property Name6: string write FName6;
  end;

  TMyClass = class
  private
    FName2: string;
    FName6: string;
    FName5: string;
    function GetName1: string;
    function GetName3: string;
    function GetName4: string;
    procedure SetName1(const Value: string);
    procedure SetName3(const Value: string);
  published
    property Name1: string read GetName1 write SetName1; // Template prop
    property Name2: string read FName2   write FName2;   // Template propf
    property Name3: string read GetName3 write SetName3; // Template propgs
    property Name4: string read GetName4; // Template propro
    property Name5: string read FName5;   // Template proprof
    property Name6: string write FName6; // !!! hier legt Delphi mir manchmal auch noch den Getter an, egal ob ich will oder nicht !!!
  end;
Interface-Methoden legt nicht ver Klassenvervollständigung (Strg+Shift+C) an, sondern das übernimmt "teilweise" die Code-Vervolständigung (Strg+Leertaste),
aber du mußt da selber auswählen was du willst. Wenigstens mit Multiselect, auch wenn es schwachsinn ist, denn von Interfaces müssen sowieso immer alle Methoden implementiert werden, dann könnte Delphi da auch von Selber gleich alles anlegen.

Die Codevervollständigung legt "eigentlich" alles alphaetisch an.
Und ja, mir wäre die Reihenfolge der Implementation auch lieber.
Und obwohl das alphabetisch rein kommt, dreht es schnell durch, wenn einmal in der Implementation die Reihenfolge der vorher bestehenden Methoden nicht stimmt, oder wenn man überladene Methoden hat, dann wird schnell mal was zu früh eingefügt.

stahli 2. Sep 2017 14:52

AW: Interface-Unterstützung
 
@himitsu

Das Interface erzwingt ja Getter und/oder Setter, also akzeptiert kein privates Feld.
Daher wäre wünschenswert (gewesen), dass in Deinen Beispielen von der Codevervollständigung ein privates Feld fName1 angelegt und in Getter und Setter gelesen bzw. zugewiesen wird.


@all

Der ModelMaker Code Explorer scheint wirklich schon sehr gut das zu sein, was ich mir wünschen würde.
Da stellt sich die Frage: Lohnt es sich vielleicht direkt, gleich Nägel mit Köpfen zu machen und auch den ModelMaker zu nutzen?
Wenn der MM genutzt wird, bringt dann der MMX noch etwas?

Ich kann die Zusammenhänge immer noch nicht so genau einordnen. :-(

Uwe Raabe 2. Sep 2017 15:23

AW: Interface-Unterstützung
 
Zitat:

Zitat von stahli (Beitrag 1380180)
Der ModelMaker Code Explorer scheint wirklich schon sehr gut das zu sein, was ich mir wünschen würde.
Da stellt sich die Frage: Lohnt es sich vielleicht direkt, gleich Nägel mit Köpfen zu machen und auch den ModelMaker zu nutzen?
Wenn der MM genutzt wird, bringt dann der MMX noch etwas?

Die beiden ergänzen sich zwar, aber ich denke für dich ist MMX die bessere Wahl, da dieser direkt in der IDE arbeitet. Für MM müsstest du immer mit zwei separaten Programmen arbeiten: MM für das Klassen-Design und die IDE für das visuelle Design und das Compilieren. Auch was den Source-Editor betrifft, ist MM der IDE deutlich unterlegen.

himitsu 2. Sep 2017 16:58

AW: Interface-Unterstützung
 
Nein, wenn read/write nicht auf ein Feld, sondern ausschließlich auf Setter/Getter verweisen, dann wird niemald automatisch ein Feld angelegt,
denn was wäre, wenn der Entwickler kein Feld braucht und dann immer wieder Eines angelegt würde?

Das wäre wie ein Kühlschrank, der immer gleich automatisch etwas bestellt, wenn es alle wird.
Dabei hab ich das nur aufgegessen, weil ich keine Lust hatte es wegzuwerfen, es aber nie wieder haben will, weil es nicht so gut schmeckt, aber immer wenn es endlich weg ist, wird sofort Nachschub geliefert. :wall:

stahli 2. Sep 2017 17:25

AW: Interface-Unterstützung
 
Ein automatisches Feld sollte die Codevervollständigung m.E. anlegen und im Getter/Setter verwenden, wenn Getter und Setter erzeugt werden.
Braucht der Entwickler das dann nicht, ist das schnell gelöscht und im Getter/Setter entfernt.
Wird später nochmal die Codevervollständigung benutzt, darf das Feld natürlich nicht nochmal ein privates Feld erzeugen (und der Kühlschrank würde Dir kein Bier nachbestellen ;-) ).

In das Getter/Setter-Dilemma wird man ja nur gezwungen, weil die Interface-Regeln das so erfordern. Ein privates Feld kann man dort ja nicht angeben bzw. dies offen lassen.

Uwe Raabe 2. Sep 2017 17:33

AW: Interface-Unterstützung
 
Zitat:

Zitat von himitsu (Beitrag 1380184)
Nein, wenn read/write nicht auf ein Feld, sondern ausschließlich auf Setter/Getter verweisen, dann wird niemald automatisch ein Feld angelegt,

MMX bietet eine (vom Benutzer erweiterbare) Reihe von möglichen Implementationen für die Getter und Setter bei der Implementierung eines Properties an. Darunter auch das Lesen und Schreiben eines Feldes, daß in diesem Zusammenhang gleich mit angelegt, initialisiert und im Falle einer Instanz bei Bedarf auch wieder freigegeben wird.

Vielleicht sollte ich wirklich mal ein paar Filmchen über MMX machen. Manch einer weiß offenbar gar nicht was er verpasst :-D


Alle Zeitangaben in WEZ +1. Es ist jetzt 21:25 Uhr.
Seite 1 von 7  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