![]() |
Unit-Design - was bevorzugt ihr?
Ich habe mal in einem Forum eine Art und Weis gesehen eine Unit anzulegen, die mir noch immer zu denken gibt. Ich bin mir nicht mehr sicher ob das in diesem Forum war oder woanders.
Die Suche hilft mir da nicht weiter. Im Grunde war es eine Unit wie die erste. Welche bevorzugt ihr? #1
Delphi-Quellcode:
oder eher #2
unit uTest;
interface // uses ; type TTestUnit = record private public class procedure TestProzedur(const AParam: string); static; end; implementation // uses ; class procedure TTestUnit.TestProzedur(const AParam: string); begin // do some stuff end; end. // Aufruf: TTestUnit.TestProzedur('123');
Delphi-Quellcode:
:idea:
unit uTest;
interface // uses ; procedure TestProzedur(const AParam: string); implementation // uses ; procedure TestProzedur(const AParam: string); begin // do some stuff end; end. // Aufruf: uTest.TestProzedur('123'); |
AW: Unit-Design - was bevorzugt ihr?
Lieber Nr. 1.
|
AW: Unit-Design - was bevorzugt ihr?
Weder noch.
Globale Methoden werden kaum besser wenn man sie in einen record packt. |
AW: Unit-Design - was bevorzugt ihr?
Interessant. Ich hätte eigentlich gedacht, dass #1 total gehasst wird.
Ich persönlich mag vom Code her eher #1. Aber wenns um Änderungen geht ist #2 besser, da hier weniger zu ändern ist. |
AW: Unit-Design - was bevorzugt ihr?
Zitat:
Zitat:
|
AW: Unit-Design - was bevorzugt ihr?
Zitat:
Zitat:
|
AW: Unit-Design - was bevorzugt ihr?
Zitat:
|
AW: Unit-Design - was bevorzugt ihr?
.. wenn Du #1 verwendest kannst Du im Source(in dem die Unit verwendet wird) codecompletion verwenden.
Bei #2 nicht. Grüße Klaus |
AW: Unit-Design - was bevorzugt ihr?
Ich glaube freimatz meinte, dass TTestUnit ein record und keine class ist. Wobei das in diesem speziellen Fall keinen Unterschied machen dürfte.
Ich persönlich bevorzuge auch die Variante #1 (aber eher als class). |
AW: Unit-Design - was bevorzugt ihr?
Statt
Delphi-Quellcode:
eine
Record
Delphi-Quellcode:
oder
Class Abstract
Delphi-Quellcode:
macht von der "Verwendung" her keinen großen Unterschied.
Class Sealed
Der "Unterschied" ist nur in Bezug auf Vererbung und die RTTI bezogen. Aber ich würde bei Records auf jeden Fall noch
Delphi-Quellcode:
mit angeben, um den "unsichtbaren" Self-Parameter loszuwerden, da Self ohne Vererbung keinen Sinn macht.
static
Ich verwende auch gern Record statt Class, da dort der RTTI-Overhead einen Hauch geringer ist, aber im Prinzip kann es jeder machen wie er will. Record verwende ich quasi so ähnlich wie den "Namespace" in anderen Sprachen. |
AW: Unit-Design - was bevorzugt ihr?
Zitat:
|
AW: Unit-Design - was bevorzugt ihr?
Zitat:
Zitat:
|
AW: Unit-Design - was bevorzugt ihr?
Zitat:
Delphi-Quellcode:
wird den Methoden ein versteckter
static
Delphi-Quellcode:
Parameter übergeben, welcher die aktuelle Objektinszanz beinhaltet (bzw. einen Zeiger auf die TClass, sofern es sich um eine Class-Method handelt). Das ist natürlich relativ witzlos, wenn man den
Self
Delphi-Quellcode:
eh nur als Namespace benutzt und nichtmal instanziiert.
record
|
AW: Unit-Design - was bevorzugt ihr?
Im Beispiel #1 haben die Methoden doch static :P
Delphi-Quellcode:
type
TTestUnit = record private public class procedure TestProzedur(const AParam: string); static; end; |
AW: Unit-Design - was bevorzugt ihr?
Ist Euch eigentlich aufgefallen, das Ihr nicht über "Unit-Design" sondern über die Anwendung von Records contra Classes diskutiert?
Beides hat seine Berechtigung und ich setze jeweils das ein was mir besser in den Kram passt. Und das schließt eine spätere Änderung nicht aus. Da gibt es kein entweder oder. (und ich habe noch jede Menge Units, die einfach nur Funktionssammlungen sind. Solange die vernünftig arbeiten, werde ich da nichts ändern. Gruß K-H |
AW: Unit-Design - was bevorzugt ihr?
Ich lege alles in Klassen. Dort benutze ich dann aber auch noch Records zur weiteren Strukturierung. Zum Beispiel gibt es dann nicht (als fiktive Beispiele):
Delphi-Quellcode:
sondern:
StrToPerson
TryStrToPerson HashMD5Salted usw.
Delphi-Quellcode:
Auf die Weise findet man finde ich sehr viel schneller was man sucht, weil man nicht eine hingeworfene Anzahl an Funktionen hat, sondern eine saubere Struktur, durch die man per Syntaxergänzung schnell durch ist.
TStringTools.StrTo.Person
TStringTools.TryStrTo.Person TStringTools.Hash.MD5Salted usw. Einen größeren Unterschied macht die Sache auch bei der Umbenennung einer Unit. Schreibt man den Unitnamen immer vor eine lose Funktion, muss man diesen unterhalb von implementation an x Stellen anpassen. Schreibt man dort nur den Klassennamen hin, beschränkt sich die Änderung jeweils auf die uses Klausel. Schreibt man den Unitnamen aber nicht hin bei losen Funktionen, weiß man nicht woher die Funktionen stammten... Die beiden großen Vorteile sehe ich, wenn man nicht lose Funktionen nutzt. |
AW: Unit-Design - was bevorzugt ihr?
Zitat:
Zitat:
Aber ernsthaft gefragt, schleppe ich nicht irgendwelchen Overhead mit, wenn ich irgendwelche Allerweltsfunktionen in eine Klasse packe? War da nicht mal was wie, nur was gebraucht wird, wird auch kompiliert? Gruß K-H |
AW: Unit-Design - was bevorzugt ihr?
Zitat:
|
AW: Unit-Design - was bevorzugt ihr?
Kompiliert wird immer alles.
Was am Ende ins Programm gelinkt wird, ist eine andere Sache. Editor -> PreCompiler (LLVM bei den neueren Compilern) -> Compiler -> Linker -> AfterBuildZeugs Auch bei Klassen/Records können Felder/Methoden weggelassen werden, oder gar die ganze Klasse (außer man ist so intelligent und bindet z.B. in Initialization eine Initprozedur ein, anstatt den Class-Constructor zu nutzen) Natürlich ist genau definiert wann welche Mehtode verwendet wird, wenn es mehrere gleichnahmige gibt, aber das muß nicht immer mit dem übereinstimmen, was man grade glaubt zu wissen, falls man z.B. diese andere IntToStr/StrToInt nicht kennt oder grade im Kopf hat. |
AW: Unit-Design - was bevorzugt ihr?
Zitat:
Das haben wir dann neu strukturiert, so dass aus string_tools.pas zuerst StringUtils.pas und nun Common.Utils.StringTools.pas wurde (natürlich auch im Verzeichnis common/utils). Neue Unit landen gleich in dieser geordneten Struktur. Insofern wurden bei uns eher die alten Unit umbenannt. Aber das ist natürlich bei jedem anders, das sollte kein Widerspruch sein. ;-) |
AW: Unit-Design - was bevorzugt ihr?
Wo wir schon bei Units sind ...
Ich benutze auch gerne weitere Verschachtelungen durch . in der Art String.Utils.Converter.pas Das mache ich mittlerweile in vorrauseilendem Gehorsam, also auch wenn es String.pas und String.Utils.pas noch gar nicht gibt :stupid: Rollo |
AW: Unit-Design - was bevorzugt ihr?
Zitat:
Gruß K-H |
AW: Unit-Design - was bevorzugt ihr?
Ich ändere gerade auch alles um, damit mein Chaos etwas geordneter wird.
In eine eben angelegte Datei habe ich bereits 22 Methoden gesteckt. Die Datei hat mittlerweile komplett 745 Zeilen. Bis wie viel Zeilen ist eine Datei denn noch OK, wenn thematisch alle Methoden die da drin sind zusammenpassen? |
AW: Unit-Design - was bevorzugt ihr?
Zitat:
Ich habe auch noch Projekte wo es Units gibt, die gesammelte Proceduren und Funktionen habe... (> 7000 LOC) Da hat aber auch so gut wie keine Procedure etwas mit der anderen zu tun... Und i.d.R haben die alle 2 Versionen
Delphi-Quellcode:
Ich rede mich raus mit : Gewachsener Code seit 1984. :stupid:
Procedure Foo(Const AValue : AnsiString);overload;
Procedure Foo(Const AValue : WideString);overload; Wenn ich Proceduren für Typen baue, dann immer in einer Class Abstract oder z.B. für TArray<T> hier ist alleine die Klassendefinition fast 200 LOC. Mavarik |
AW: Unit-Design - was bevorzugt ihr?
Zitat:
Zitat:
Zitat:
|
AW: Unit-Design - was bevorzugt ihr?
Gewachsene Libraries sind/werden wohl immer chaotisch, ich sehe das ganz locker.
Man sollte nur permanent an Verbesserungen und Reduzierungen von Redundanz und Kopplung arbeiten. Dann wir schon alles gut :stupid: Hauptsache der Codeowner kennt sich im Dschungel noch aus. Rollo |
AW: Unit-Design - was bevorzugt ihr?
Zitat:
Delphi-Quellcode:
Mir ging es auf die Nerven, dass es von offizieller Seit nur eine davon gab. Also habe ich mir die genommen, in meine Sammlung gepackt und zwei hinzugefügt.
function IfThen(aValue: Boolean; const ATrue, AFalse: Integer): Integer; overload;
begin if aValue then Result := ATrue else Result := AFalse; end; function IfThen(aValue: Boolean; const ATrue, AFalse: string): string; overload; begin if aValue then Result := ATrue else Result := AFalse; end; function IfThen(aValue: Boolean; const ATrue, AFalse: Boolean): Boolean; overload; begin if aValue then Result := ATrue else Result := AFalse; end; Auf diese Art und Weise konnte ich viel Code sparen alà
Delphi-Quellcode:
// Vorher
if A = B then s := 'C' else s := 'D'; // Nachher s := IfThen(A = B, 'C', 'D'); |
AW: Unit-Design - was bevorzugt ihr?
Zitat:
|
AW: Unit-Design - was bevorzugt ihr?
Zitat:
|
AW: Unit-Design - was bevorzugt ihr?
Könnte man das nicht auch so lösen (ungetestet)?
Delphi-Quellcode:
Aufruf dann z.B.
type
TGenericCompare<T> = record public class function IfThen(Expression: Boolean; const AThen, AElse: T): T; static; end; class function TGenericCompare<T>.IfThen(Expression: Boolean; const AThen, AElse: T): T; begin if Expression then Result := AThen else Result := AElse; end;
Delphi-Quellcode:
procedure TfrmTest.ButtonTestClick(Sender: TObject);
var s: string; begin s := TGenericCompare<string>.IfThen(1 = 1, 'Ja', 'Nein'); ShowMessage(s); end; |
AW: Unit-Design - was bevorzugt ihr?
Kann man, so etwas ähnliches benutze ich selbst auch, nur dass ich den generischen Parameter der Methode statt der Klasse bzw. dem Record gegeben habe.
|
AW: Unit-Design - was bevorzugt ihr?
Der Nachteil dieser Funktion im Gegensatz zum direkten Ausschreiben ist halt, daß beide Ergebnisse als Funktionsparameter ausgewertet werden. Das mag nicht immer wünschenswert sein:
Delphi-Quellcode:
IfThen(Sender <> nil, Sender.Classname, '');
|
AW: Unit-Design - was bevorzugt ihr?
War ja nur 'ne Idee, zig Überladungen für alle möglichen Datentypen machen den Code halt unübersichtlich IMO.
|
AW: Unit-Design - was bevorzugt ihr?
Ihr sprecht ja von zwei verschiedenen Sachen. Uwes Hinweis gilt ja für beide Lösungen mit IfThen. Deshalb ist IfThen ja auch nicht sinnvoll für zeitkritische Codestellen.
|
AW: Unit-Design - was bevorzugt ihr?
Zum Ursprungsthema: Ohne weitere Information würde ich mal sagen #2. Man muss ja nicht alles machen wie Java.
Wenn es eine globale Funktion ist, dann ist es halt eine globale Funktion. Wird auch nicht besser, wenn man noch eine Klasse drumherum packt. Das ist eigentlich nur Boilerplate-Code, der keinen zusätzlichen Nutzen bringt. Das "Namespace" oder Code-Completion-Argument lasse ich auch nicht gelten, denn dazu kann man auch genau so gut den Unit-Namen verwenden (Weiß vielleicht nicht jeder, vor allem wenn er von einer anderen Sprache wie C++ kommt, die kein richtiges Modul-System haben). In Pascal-Sprachen stellt die Unit an sich schon eine Kapselung dar, da braucht man nicht noch eine Kapselung in der Kapselung. Das ist wohl diese Java-Denke. "Alles muss ein Objekt sein". OOP ist schön und gut, da wo es Sinn macht, aber es ist auch nicht das einzige, was es gibt. |
AW: Unit-Design - was bevorzugt ihr?
Zitat:
Da bevorzuge ich lieber die Eingabe von TStringUtils im Code :P |
AW: Unit-Design - was bevorzugt ihr?
Warum nicht einfach der Unit einen schöneren Namen geben?
|
AW: Unit-Design - was bevorzugt ihr?
Zitat:
Gruß K-H |
AW: Unit-Design - was bevorzugt ihr?
Zitat:
|
AW: Unit-Design - was bevorzugt ihr?
Hallo,
da war doch diese Unit mit 32.000 Zeilen Quellcode unter Delphi 1, zum Glück kam D2 und ich konnte endlich > 32.767 ;) |
Alle Zeitangaben in WEZ +1. Es ist jetzt 16:02 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