![]() |
AW: Interface-Unterstützung
@Uwe
Was ist denn an meinen Anforderungen speziell? Ich hätte gedacht, dass jeder, der intensiver Interfaces benutzt, über das gleiche Problem stolpert. Wenn eine Klasse mehrere Interfaces unterstützt, kann man das nicht mehr einfach über Vererbung abfrühstücken und müsste somit mindestens einige (oder sogar alle) Member neu implementieren. Das ist besonders bei Gettern und Settern nervig, weil dort ja i.d.R. eh nur in ein privates Feld geschrieben oder daraus gelesen wird. Und dann sollte das als Standardweg halt automatisch voreingestellt werden. Bei Bedarf kann man es dann ja immer noch ändern. Als Fazit würde ich mal ziehen, dass keiner zu doof ist ;-) und das Tool mal weiter basteln. |
AW: Interface-Unterstützung
Zitat:
![]() |
AW: Interface-Unterstützung
Zitat:
- Nur ein kleiner Bruchteil der Klassen implementiert mehr als ein Interface - Es gib kaum Setter. Kurzer Überblick über eines meiner Projekte: In 171 Interfaces gibt es 239 Properties. Davon haben 18 einen Setter. Die beschreibbaren Properties verteilen sich auf 8 Interfaces, von denen es jeweils nur eine Implementierung gibt. Eventuell liegt das Problem auch in einem unglücklich gewähltem Klassen-Design, das dich zu immer wiederkehrenden Anpassungen zwingt. Hast du ein praktisches Beispiel für die mehrfache Implementierung von Interfaces mit Settern? |
AW: Interface-Unterstützung
Meinen aktuellen Quelltext will ich hier nicht veröffentlichen.
Aber ich erstelle ein früheres Projekt noch einmal neu und überarbeite dabei gleich komplett das Klassendesign (schreibe Interfaces wie am Fließband ;-) ). Ausgehen tue ich dabei immer von Interfaces (Funktionalitäten). Die tatsächlichen Klassen sind hinter einer Factory versteckt, so dass die Businesslogik nur noch die Interfaces kennt und benutzt. Da es viele Überschneidungen der Funktionalitäten gibt, müssen mehrere Klassen auch mehrere Interfaces unterstützen. Ok, mag sein, dass mein Klassendesign schon etwas ausgefallen ist und mir diese IDE-Schwäche deshalb besonders auffällt. Aber stören würde mich das tatsächlich auch bei weniger Mehrfach-Interfaces. |
AW: Interface-Unterstützung
Danke für den Tip mit dem Interface. Ich habe bisher den MMX nur zur Anzeige der Methoden genommen.
Etwas off-topic aber ich bekomme das Bookmark 7 beim MMX nicht weg. Egal was ich in den Optionen einstelle. Angeblich stammt das aus 'Drop Bookmark on Start Search Position' ... Aber immer wenn ich rumpfrimmle kommt das Bookmark 7 obwohl es auf none steht in den Optionen. Kommt das bei dir auch? Zitat:
|
AW: Interface-Unterstützung
Zitat:
|
AW: Interface-Unterstützung
Danke. Uwe.
Plag dich nicht. Beizeiten. Es erscheint einfach ein Bookmark 7 und wenn ich MMX deinstalliere kommt es nicht mehr. Seit XE ist das so, egal mit welchem MMX. Es erscheint auch zufällig. Es erscheint dann auf jeden Fall wenn der MMX im Code rumpfrimmelt an der Stelle wo das passiert. Die Idee ist an sich ja nicht falsch. Ich muss noch rausfinden wenn es passiert. Es ist bspw. passiert wie in der Strukuranzeige des MMX oben das Interface über die Klasse gezogen hat. Dann hat der MMX ganz korrekt die Deklarationen durchgezogen und eine Bookmark platziert nämlich Bookmark 7 (default Einstellung für Search - an der ersten Fundstelle Positionieren). Ich schaue noch zuvor ob sich das Bookmark 7 ändert wenn dieses spezifische Bookmark auf bspw. 8 umstelle. Dann melde ich mich gerne mal. Bitte keinen Aufwand treiben. Danke nochmal für den Tip.:thumb: (* Ich bin schon sehr froh, dass überhaupt die Methoden usw... der Unit sauber strukturiert sehe*). Allein verwende ich eher sehr übersichtliche Anzahl von Codezeilen in Units, aber nicht so exzessiv sodass ich während des Debuggens zuviel in Einzeilern herumhüpfe und ich halt die aktuellen Prozeduren eher oben und nicht unten ala FIFO Queue, denn ich arbeite eher Bottom Up. Lieben Gruß Zitat:
|
AW: Interface-Unterstützung
Vielleicht noch ergänzend zum MMX:
![]() |
AW: Interface-Unterstützung
Danke
Zitat:
|
AW: Interface-Unterstützung
Ja, genau diese Funktionen sind an MMX sehr interessant. :thumb:
Mehr habe ich bei Interfaces auch noch nie gebraucht. |
AW: Interface-Unterstützung
Zitat:
Muss ich dann in jede Klasse und das dort pasten, damit er ne simple Signatur updatet oder neue Methoden hinufügt? |
AW: Interface-Unterstützung
Zitat:
Ich könnte mir aber vorstellen, daß MMX die implementierenden Klassen zumindest im aktuellen Projekt/Projektgruppe automatisch ausfindig macht und eine Synchronisierung anbietet oder optional automatisch durchführt. Wäre zumindest einen Feature-Request wert. |
AW: Interface-Unterstützung
Hier nochmal ein neuer Zwischenstand.
Im ersten Text ist verkürzt eine Klasse deklariert und nach Tastendruck wird daraus das nachfolgende Ergebnis generiert. Es geht noch nicht alles, aber die Idee dahinter sollte schon mal gut erkennbar sein. Es werden die Methoden, Properties und privaten Felder erzeugt und auch die Methoden soweit möglich vorausgefüllt. Das natürlich nur, wenn sie neu generiert werden. Spätere händische Änderungen bleiben natürlich bei künftigen Optimierungen erhalten. Der Implementationsteil wird analog dem Interfaceteil sortiert. Das gilt auch, wenn die Reihenfolge der Klassen oder Klassenmember im Interfaceteil nachträglich verändert wird. Bei der nächsten Optimierung werden dann die Klassen und Methoden im Implementationsteil an die neue Reihenfolge im Interfaceteil angepasst. Derzeit habe ich die Getter und Setter mit _get_... und _set_ benannt und die privaten Felder mit "f". Außerdem habe ich in generierten Methoden ein ? eingesetzt, damit man die Methoden mindestens einmal bearbeitet. In Settern prüfe ich erst auf eine Werteänderung. Das alles lässt sich natürlich ggf. auch über Optionen steuern, falls daran Bedarf wäre. Original:
Delphi-Quellcode:
unit Unit2;
interface uses System.Classes, Vcl.Graphics, System.Types, System.UITypes; const aConst = 100; type TClass1 = class private procedure PrivProc; virtual; public constructor Create; virtual; destructor Destroy; override; public procedure Execute(NewVal: String); virtual; function TestFunc(var Val1: Integer): Boolean; prop PropString: string; prop PropInteger: Integer rf; prop PropBoolean: Boolean v ws vi; prop PropByte: Byte s; prop PropWord: Word c w rf; prop PropString2: string c vi; end; implementation end. Ergebnis:
Delphi-Quellcode:
unit Unit2;
interface uses System.Classes, Vcl.Graphics, System.Types, System.UITypes; const aConst = 100; type TClass1 = class private fPropString: string; fPropInteger: Integer; fPropBoolean: Boolean; fPropByte: Byte; fPropWord: Word; fPropString2: string; procedure PrivProc; virtual; function _get_PropString: string; procedure _set_PropString(aValue: string); procedure _set_PropBoolean(var aValue: Boolean); virtual; function _get_PropByte: Byte; stdcall; procedure _set_PropByte(aValue: Byte); stdcall; function _get_PropString2: string; virtual; procedure _set_PropString2(const aValue: string); virtual; public constructor Create; virtual; destructor Destroy; override; procedure Execute(NewVal: String); virtual; function TestFunc(var Val1: Integer) Boolean property PropString: string read _get_PropString write _set_PropString; property PropInteger: Integer read fPropInteger; property PropBoolean: Boolean write _set_PropBoolean; property PropByte: Byte read _get_PropByte write _set_PropByte; property PropWord: Word read fPropWord; property PropString2: string read _get_PropString2 write _set_PropString2; end; implementation { TClass1 } constructor TClass1.Create; begin end; destructor TClass1.Destroy; begin end procedure TClass1.PrivProc; begin ?; end function TClass1._get_PropString: string; begin Result := fPropString; end procedure TClass1._set_PropString(aValue: string); begin if (fPropString <> aValue) then begin fPropString := aValue; end; end procedure TClass1._set_PropBoolean(var aValue: Boolean); begin if (fPropBoolean <> aValue) then begin fPropBoolean := aValue; end; end function TClass1._get_PropByte: Byte; begin Result := fPropByte; end procedure TClass1._set_PropByte(aValue: Byte); begin if (fPropByte <> aValue) then begin fPropByte := aValue; end; end function TClass1._get_PropString2: string; begin Result := fPropString2; end procedure TClass1._set_PropString2(const aValue: string); begin if (fPropString2 <> aValue) then begin fPropString2 := aValue; end; end procedure TClass1.Execute(NewVal: String); begin ?; end function TClass1.TestFunc(var Val1: Integer): Boolean; begin Result := ?; end end. Als nächstes will ich jetzt die Optimierung von Interfaces und von Klassen, die Interfaces verwenden, umsetzen. Dann würden entsprechende Deklarationen wie oben im Interface automatisch auf die das Interface verwendenden Klassen durchschlagen. In der Klasse gäbe es dann Sektionen wie
Delphi-Quellcode:
Spätere Änderungen im Interface würden automatisch auf die Klassen durchschlagen. Das wird (mit einer entsprechenden Anweisung) sogar für Umbenennungen von Properties und Methoden möglich sein, so dass eine InterfaceMember-Namensänderung nacheinander in mehreren Projekten nacheinander automatisiert durchgeführt werden kann (allerdings dann wohl nur bei den Klassenmembern, nicht als wirkliches Refactoring).
private // Intf1
fProp: Integer protected // Intf1 function _get_Prop: Integer; public // Intf1 property Prop: Integer read _get_Prop; Wird das jetzt interessanter? |
AW: Interface-Unterstützung
Für mich Nein, sorry. Ich nehm meist den MMX für so was.
Übrigens habe ich mir auch ein Tool für DTO-Datenklassen gemacht. Man schreibt ein interface (mit oder ohne Getter) und das Tool ergänzt die interfaces, erstellt die Klassen die das implementieren und dazu noch Fabrikmethoden und auf Wunsch records dazu. |
AW: Interface-Unterstützung
Zitat:
Dass da immer wieder jemand sein eigenes Süppchen kocht, ist echt suboptimal. Da das ein Tool vor allem für dich selbst ist, bist du da natürlich frei, aber so wird es dann wohl auch eher eine Lösung bleiben, die sonst nicht viele nutzen möchten. Gerade die Verwendung von Standards ist in vielen Bereichen wirklich hilfreich (und trägt zur Verbreitung einer Lösung bei)... Was ich tatsächlich nützlich finden würde, wäre, wenn man die Property normal hinschreiben könnte ohne read und write und dann analog zur Klassenvervollständigung Getter und Setter ergänzt würden. Wie ich das aktuell mache, hatte ich ja schon geschrieben: ![]() Das geht zwar sehr schnell, auch bei mehreren Properties, aber wenn das in einem Schritt ginge, wäre das schon schön. Mit deiner Kurzschreibweise kann ich mich leider gar nicht anfreunden. Die paar Millisekunden Zeitersparnis beim Tippen (prop vs. property) sind für mich nicht relevant, da schreibe ich es lieber richtig... Wenn statt
Delphi-Quellcode:
das ganze auch mit
prop PropString: string;
Delphi-Quellcode:
gehen würde, wäre das schon gut. Dann könnte es eine Alternative zur Klassenvervollständigung werden.
property PropString: string;
Trotzdem geht mit MMX aktuell noch deutlich mehr. |
AW: Interface-Unterstützung
@freimatz
Ich hatte auch mal einen Codegenerator, der mir anhand von Datenstrukturen komplette Klassen erstellt hat. Das ist aber nicht vergleichbar mit der Änderung einer bestehenden Unit. Kann Dein Tool so etwas auch? Ich würde es dann gerne übernehmen, wobei ich mit meinem jetzt auch schon recht weit und zufrieden bin. @jaenicke _get_ und _set_ verwende ich gern, weil Getter und Setter ja eher Hilfskonstrukte sind, die normalerweise nicht extern aufgerufen werden. So sind "echte Funktionen" wie GetBestFriends(1000) durch die Namensgebung besser von Gettern und Settern zu unterscheiden. Aber wie gesagt, das ließe sich ja völlig unproblematisch über Optionen steuern. Auch "property" auf Wunsch auszuschreiben wäre kein Problem. Die Codevervollständigung würde dann analog "prop" zuschlagen, wenn darauf kein read und kein write folgt (sonst wäre das Property ja schon mit einem read und/oder write vollständig deklariert und dürfte nicht mehr automatisch verändert werden). Klar ist der MMX komplexer, mir aber zu umständlich. Mein Tool sehe ich einfach als Codevervollständigung 2.0 + UnitSortierer. Meiner Arbeitsweise kommt das (wenn es fertig wird, wie erhofft) sehr viel mehr entgegen. Wenn man in Interfaces oder im Interfaceteil von Klassen bestimmte Vorgaben trifft, ergibt sich daraus bereits exakt, was an anderen Stellen nochmal exakt so geschrieben werden muss. Und genau das nervt mich inzwischen extrem. |
AW: Interface-Unterstützung
Mein Tool ist nicht unviversell brauchbar. Erstmal ist er nur für Transferobjekte da. Weiter wird formatierter Code verlangt so wie es unser Formatter macht. Dann ist das Tool ein Gebastel und mit <duck>VS/C#</duck> erstellt. Neuerdings sollte das Tool auch mit bestehenden units klar kommen.
Zum Verständnis noch ein Beispiel: Gegeben
Delphi-Quellcode:
Dann wird da draus:
IBlafaselCalculatorSourceData = interface(IBlaCalculatorSourceData)
['{FDFBCC49-C16F-4BC1-B6BF-7926EA37113F}'] property ToleranceZoneGeometry: IToleranceZoneGeometryBase; property PreparedPoints: TPreparedPoints; end;
Delphi-Quellcode:
Der Record ist hier noch nicht dabei. Auch etliche REGIONS habe ich weggelassen.
IBlafaselCalculatorSourceData = interface(IBlaCalculatorSourceData)
['{FDFBCC49-C16F-4BC1-B6BF-7926EA37113F}'] function GetToleranceZoneGeometry(): IToleranceZoneGeometryBase; function GetPreparedPoints(): TPreparedPoints; property ToleranceZoneGeometry: IToleranceZoneGeometryBase read GetToleranceZoneGeometry; property PreparedPoints: TPreparedPoints read GetPreparedPoints; end; ... function CreateBlafaselCalculatorSourceData( ... Zeug von Vorfahre const p_ToleranceZoneGeometry: IToleranceZoneGeometryBase; const p_PreparedPoints : TPreparedPoints): IBlafaselCalculatorSourceData; ... TBlafaselCalculatorSourceData = class(TBlaCalculatorSourceData, IBlafaselCalculatorSourceData) strict private FToleranceZoneGeometry: IToleranceZoneGeometryBase; FPreparedPoints : TPreparedPoints; function GetToleranceZoneGeometry(): IToleranceZoneGeometryBase; function GetPreparedPoints(): TPreparedPoints; public constructor Create( ... Zeug von Vorfahre const p_ToleranceZoneGeometry: IToleranceZoneGeometryBase; const p_PreparedPoints : TPreparedPoints); property ToleranceZoneGeometry: IToleranceZoneGeometryBase read GetToleranceZoneGeometry; property PreparedPoints: TPreparedPoints read GetPreparedPoints; end; ... constructor TBlafaselCalculatorSourceData.Create( ... Zeug von Vorfahre const p_ToleranceZoneGeometry: IToleranceZoneGeometryBase; const p_PreparedPoints : TPreparedPoints); begin inherited Create(... Zeug von Vorfahre); FToleranceZoneGeometry := p_ToleranceZoneGeometry; FPreparedPoints := p_PreparedPoints; end; ... constructor TBlafaselCalculatorSourceData.Create( ... Zeug von Vorfahre const p_ToleranceZoneGeometry: IToleranceZoneGeometryBase; const p_PreparedPoints : TPreparedPoints); begin inherited Create(... Zeug von Vorfahre); FToleranceZoneGeometry := p_ToleranceZoneGeometry; FPreparedPoints := p_PreparedPoints; end; ... constructor TBlafaselCalculatorSourceData.Create( ... Zeug von Vorfahre const p_ToleranceZoneGeometry: IToleranceZoneGeometryBase; const p_PreparedPoints : TPreparedPoints); begin inherited Create(... Zeug von Vorfahre); FToleranceZoneGeometry := p_ToleranceZoneGeometry; FPreparedPoints := p_PreparedPoints; end; function TBlafaselCalculatorSourceData.GetToleranceZoneGeometry(): IToleranceZoneGeometryBase; begin Result := FToleranceZoneGeometry; end; function TBlafaselCalculatorSourceData.GetPreparedPoints(): TPreparedPoints; begin Result := FPreparedPoints; end; ... function CreateBlafaselCalculatorSourceData( ... Zeug von Vorfahre const p_ToleranceZoneGeometry: IToleranceZoneGeometryBase; const p_PreparedPoints : TPreparedPoints): IBlafaselCalculatorSourceData; begin Result := TBlafaselCalculatorSourceData.Create(... Zeug von Vorfahre, p_ToleranceZoneGeometry, p_PreparedPoints); end; |
AW: Interface-Unterstützung
Liste der Anhänge anzeigen (Anzahl: 1)
Ich habe jetzt noch einen neuen Ansatz realisiert.
Das Tool analysiert die zusammenhängenden Blöcke und kennzeichnet sie farblich. (Umgebaut wird die Unit noch nicht.) Es ist doch überraschend, wie unstrukturiert die Pascal-Unit wirklich ist. Es ist gar nicht immer so eindeutig zu erkennen, wo eine Anweisung zu Ende ist. Das Tool ist ja kein Compiler und soll gar nicht wissen, was jedes Wort bedeutet. Es muss sich daher allein an der Struktur des Textes orientieren. "virtual;" hinter einer Prozedur-Deklaration gehört noch zu ihr. "end;" aber nicht. "Quatsch ;" würde mit zur Prozedur gehören (auch wenn es natürlich kein Pascal-Schlüsselwort ist, könnte aber vielleicht ja in 2 Jahren eins werden ;-) ) "Quatsch!" würde wohl irgendwie zur Klassendeklaration gehören. Zusätzlich können überall Leerzeichen, Kommentare und Zeichenumbrüche dazwischen stehen. Manche Anweisungen müssen mit ";" abgeschlossen werden, andere nicht, weitere werden trotz ";" fortgesetzt (wie bei "virtual") Ich bin auf einem guten Weg, denke ich, aber es war kein leichter. :-) PS: Kennt jemand sich mit den Tool-Api´s aus im Sinne Refactoring und Code-Formatierung? |
AW: Interface-Unterstützung
Zitat:
Ja, du machst keinen Compiler. Aber die Analyse sollte auf dem gleichen Weg passieren, also mit einem Parser. Sonst wird der Weg nie zu Ende sein. Ständig kommt dann irgendwelcher "Quatsch" daher an den du nicht gedacht hast. Pascal ist schließlich auch eine formatfreie Sprache. Es gibt Parser. Hier in meiner Firma wird ein solcher auch verwendet um aus interfaces Mock-Objekte zu erzeugen. Auskennen tue ich mich da aber nicht, habe nur einmal was daran geändert. |
AW: Interface-Unterstützung
Zitat:
Denn strukturiert ist das ganze schon eindeutig, nur wenn du mal z.B. in den genannten Parser hineinschaust, siehst du auch wie viele Fälle da eigentlich behandelt werden müssen... |
AW: Interface-Unterstützung
Hi,
auch wenn mein Ansatz nicht so auf allgemeine Begeisterung stößt will ich mal etwas grundsätzliches fragen: Welche Ordnung würdet Ihr innerhalb einer Interface- und Klassendeklaration bevorzugen? Mein Tool soll ja einiges automatisieren. Jetzt stellt sich die Frage, wie es da heran gehen sollte. Unabhängig davon, dass man natürlich (falls es doch mal Interesse gibt) auch Optionen anbieten sollte, möchte ich mal Eure Meinungen dazu anfragen. Im Interface werden bei Properties die Getter und Setter ergänzt. Ich würde diese jeweils unmittelbar vor den Properties einfügen in der Reihenfolge Getter (wenn nötig), Setter (wenn nötig), Property. Macht Ihr das anders? Sollte vor dem Block noch eine Leerzeile zur besseren Übersichtlichkeit eingefügt werden? Bei den Klassen habe ich verschiedene Ideen. Class1: Man könnte alles (klasseneigene und Interface-Member) zusammen in die normalen Sektionen (private, protected und public) schreiben. Class2: Oder man erzeugt eigene Sektionen (private, protected und public) pro Interface und beschriftet diese (mit einem Kommentar). Class3: Wie Class2 aber die Interface-Sektionen kommen alle zum Schluss. Class4: Alle Interface-Member kommen einfach in eine beschriftete public-Sektion. Im letzten Beispiel habe ich ich auch mal eine eigene Sektion vorgesehen, in die alle Getter und Setter kommen könnten (entweder nur die von der Klasse selbst oder auch alle Getter und Setter, die zu den Interfaces gehören). Zu entscheiden wäre auch, ob private Felder sowie Getter und Setter jetzt eher in protected oder private sections gehören. Das Tool soll bestehende Ordnungen NICHT durcheinander bringen aber ich müsste entscheiden, wie es mit automatischen Ergänzungen umgehen soll. Was sind da Eure Ideen und Meinungen?
Delphi-Quellcode:
interface
IIntf1 = interface procedure Proc(Param: String); function Func(var Param: Integer): Boolean; function Getter1: string; procedure Setter1(aValue: string); property Prop1: string read Getter1 write Setter1; function Getter2: string; procedure Setter2(aValue: string); property Prop2: string read Getter2 write Setter2; end; TClass1 = class(TInterfacedObject, IIntf1) private fNew: String; fProp1: string; fProp2: string; protected function GetterNew: string; procedure SetterNew(aValue: string); function Getter1: string; procedure Setter1(aValue: string); function Getter2: string; procedure Setter2(aValue: string); public constructor Create; virtual; destructor Destroy; override; procedure New; procedure Proc(Param: String); function Func(var Param: Integer): Boolean; property New: string read GetterNew write SetterNew; property Prop1: string read Getter1 write Setter1; property Prop2: string read Getter2 write Setter2; end; TClass2 = class(TInterfacedObject, IIntf1) private fNew: String; private // IIntf1 fProp1: string; fProp2: string; protected function GetterNew: string; procedure SetterNew(aValue: string); protected // IIntf1 function Getter1: string; procedure Setter1(aValue: string); function Getter2: string; procedure Setter2(aValue: string); public constructor Create; virtual; destructor Destroy; override; procedure New; property New: string read GetterNew write SetterNew; public // IIntf1 procedure Proc(Param: String); function Func(var Param: Integer): Boolean; property Prop1: string read Getter1 write Setter1; property Prop2: string read Getter2 write Setter2; end; TClass3 = class(TInterfacedObject, IIntf1) private fNew: String; protected function GetterNew: string; procedure SetterNew(aValue: string); public constructor Create; virtual; destructor Destroy; override; procedure New; property New: string read GetterNew write SetterNew; private // IIntf1 fProp1: string; fProp2: string; protected // IIntf1 function Getter1: string; procedure Setter1(aValue: string); function Getter2: string; procedure Setter2(aValue: string); public // IIntf1 procedure Proc(Param: String); function Func(var Param: Integer): Boolean; property Prop1: string read Getter1 write Setter1; property Prop2: string read Getter2 write Setter2; end; TClass4 = class(TInterfacedObject, IIntf1) private fNew: String; protected // Getter&Setter function GetterNew: string; procedure SetterNew(aValue: string); public constructor Create; virtual; destructor Destroy; override; procedure New; property New: string read GetterNew write SetterNew; public // IIntf1 fProp1: string; fProp2: string; function Getter1: string; procedure Setter1(aValue: string); function Getter2: string; procedure Setter2(aValue: string); procedure Proc(Param: String); function Func(var Param: Integer): Boolean; property Prop1: string read Getter1 write Setter1; property Prop2: string read Getter2 write Setter2; end; implementation ... end. |
AW: Interface-Unterstützung
Also ich würde sagen alle Interface Methoden privat oder protected für Ableitungen (wenn notwendig).
Keine davon public in den implementierenden Klassen. Die properties selber nicht in die Klassen, nur Setter und Getter. Dadurch verhindert man das mixen von Class und Interface. Zugriff nur über das Interface. Aber das ist natürlich nur meine Meinung, bewährt sich hier aber. |
AW: Interface-Unterstützung
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:
Für das erzeugen des Interfaces habe ich ein Livetemplate... ipropgs ipropg Die Erzeugen mir ein Interface mit den propertys mit oder ohne setter. Schön wäre es wenn eine automatische Sortierung passieren würde. die propertys werden in der classe logischerweise nicht gebraucht. Zu meinen Besonderheiten: Source in der Anlage als Bild (Beispiel) da hier der Delphi-Formatter der DP - wahrscheinlich aus gutem Grund - MEINE Formatierung zerstört. 1.) In Propertys stehen die read und writes untereinander! 2.) Funktionen haben immer ein doppeltest Space, damit die Namen untereinander stehen. 3.) Setter haben immer den Parameter "AValue" 4.) In der Classe gibt es pro Interface ein "strict private" um zu signalisieren, dass diese Methoden aus dem Interface kommen. Wenn es mehr als ein Interface gibt steht hinter "strict private // IFoo" der Interfacename 5.) Die Variabel kommen jeweils unter eine eigen private Unterteilung - Natürlich mit großem "F" und Doppelpunkte untereinander. 6.) Immer ein AfterConstruction / BeforeDestruction da ich i.d.R. die Instance über eine Factory erzeuge und daher keine Create procedure verwende um parameter zu übergeben. Ich habe noch viele Kleinigkeiten die mir das Sourcecode lesen erleichtern, aber das soll erstmal reichen. Mavarik |
AW: Interface-Unterstützung
@Fritzew
Auf die Properties in den Klassen zu verzichten ist eine Überlegung wert. Andererseits hat man mit den Properties auch einen kompletten Überblick über die Klassenmember innerhalb der Klassenmethoden. Die Klassenunits verstecke ich mittlerweile regelmäßig hinter einer Factory, so dass ich auf der Projektlogik heraus ohnehin nur noch die Interfaces sehe. Also ich werde die Properties weiter in den Klassen aufnehmen, könnte das aber optional auch ausschalten lassen. Ist wohl eher Geschmacksache. @Mavarik Das Schieben von Gettern und Settern in Interfaces nach ganz oben finde ich gut. Werde ich so umsetzen. (Im Grunde sollten die gar nicht geschrieben werden müssen und im Interface stehen. Ist ja ohnehin klar, wie die aussehen müssen.) Die Properties selbst würde ich (wie oben beschrieben) eher mit in die Klassen übernehmen - optional abschaltbar. Deine Einrückungen finde ich gewöhnungsbedürftig und bin noch unschlüssig, ob ich das gut finde oder nicht so gut. Mich würde es stören, auf den Codeformatierer (von Delphi oder Third Party) verzichten zu müssen und das alles von Hand zurecht zu schieben. Wenn Du ein Property kürzer oder länger umbenennst wird das ja eine Schiebe-Orgie. Aber ich kann mal schauen, ob ich eine solche Funktion mit unterbringen kann. Das Tool müsste halt hinter "function"-Deklarationen zwei Leerzeichen einfügen und bei gleichenartigen Zeilen untereinander bestimmte "virtuelle Tabs" benutzen. Auch hatte ich schon mal überlegt, Code mit diesen Verkettungen (ich weiß gerade nicht wie man das nennt)
Code:
automatisch auszurichten, was Du immer mit den geschweiften Klammern machst.
X := Y(123).
{} Z(234); Das würde mich ja rammdösig machen... ;-) |
AW: Interface-Unterstützung
Zitat:
Hab für die Unicode umstellen schon die ein oder anderen Sourcecode Analyse geschrieben... Aber bisher fehlte mir einfach die Zeit. |
AW: Interface-Unterstützung
Hier mal ein aktueller Zwischenstand als Video:
![]() Der Optimizer funktioniert schon mal als erster Test innerhalb der IDE. Eine direkte Codeformatierung (Einrückung) habe ich noch nicht drin, will das aber auch noch ergänzen. Die anderen Features gehen für mich aber vor. Findet das JETZT vielleicht jemand interessant? Ich würde das später sehr gern kommerziell anbieten, wenn es Nachfrage gibt. Für öffentliche Tests ist es noch etwas früh. Dazu muss ich noch einiges ausbauen und ausbessern. Sofern jemand Erfahrungen mit den OTA hat und daran mitarbeiten möchte, dann gebt Bescheid... |
AW: Interface-Unterstützung
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:53 Uhr. |
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-2025 by Thomas Breitkreuz