Hallo,
ich muss, sagen ich lese die Argumente hier mit großem Interesse. Insbesondere Hagens Ausführungen zum Laufzeitverhalten sind sehr interessant. Dazu fällt mir ein, wenn ich jetzt eine Klasse baue, habe ich zwar auch in sich abgeschlossene Methoden, aber immer ein Argument mehr, welches ein Register belegt, und zwar Self.
Zitat von
Der_Unwissende:
Da von xaromz auch gesagt wurde, dass es hier Unterprozeduren gibt, würde ich sagen, dass man einen Teil von ihnen anders auslagern sollte (in eine eigene
Unit, die diese Klasse von Problemen löst (auch ohne
OOP!)).
In meinem konkreten Beispiel ist es nicht möglich, einzelne Funktionen auszulagern. Wenn die ginge, dann hätte ich es auch gemacht. Ich muss sagen, Vorschläge zu machen, ohne das Problem zu kennen, finde ich etwas komisch.
Vielleicht sollte ich mal schreiben, was mein "Monster" eigentlich macht: Es parst Textbausteine unterschiedlicher Art und richtet diese in einem Rechteck aus (mit Zeilenumbrüchen). Dabei müssen viele Faktoren bedacht werden: Zeilen- und Absatzumbrüche, Tabulatoren, Silbentrennung, Höhe des Rechtecks...
Für all diese Teilbereiche (Tabulatorberechnung, Silbentrennung usw.) benutze ich Unterfunktionen, diese werden von der Hauptschleife aufgerufen, die alle Bausteine durchgeht. In den Unterfunktionen werden aber viele Variablen gebraucht, die auch in der Hauptschleife verwendet werden (z. B. das Einfügen einer neuen Zeile in die Bausteinliste bei einem Zeilenumbruch, der in einer Unterfunktion berechnet wurde).
Klar kann ich sowas als Klasse schreiben (ich habe das sogar letzte Nacht testweise gemacht), aber: Ich benötige diese Funktion (die sehr lange dauern kann) teilweise mehrmals pro Sekunde, und da kommt es auf jeden Tick an. Ich will also nicht jedesmal erst eine Klasse erzeugen und dann Zeit bei Methodenaufrufen verschwenden. Effizienz ist hier wichtiger als alles andere. Wenn ich es besser als der Compiler könnte, hätte ich die Funktion auch komplett in Assembler gschrieben, dann hätte ich einige Tausend Zeilen.
Ich finde außerdem, dass dieses Beispiel kein gutes ist, um das Für und Wider von Nested Procedures zu diskutieren, da es eine sehr spezielle Geschichte ist. Das dürfte auch mit Riesenabstand die größte Funktion sein, die ich je geschrieben habe, und ich möchte sowas eigentlich nicht noch mal machen müssen
.
Ich habe hier übrigens noch ein schönes Beispiel für Nested Procedures. Angenommen ich habe einen Baum mit mehreren Wurzeln (also eigentlich eher einen Wald). Jetzt möchte ich alle Elemente durchgehen. Das funktioniert am Einfachsten mit einer Rekursion in einer Nested Prodecure:
Delphi-Quellcode:
type
TItem = class(TList);
procedure GoThroughTrees(Trees: TList);
procedure Walk(Item: TItem);
var
I: Integer;
begin
// Irgendetwas machen
for I := 0 to Item.Count - 1 do
Walk(Item[I]);
end;
var
I: Integer;
begin
for I := 0 to Trees.Count - 1 do
Walk(Trees[I]);
end;
Das sieht übersichtlich aus und benötigt sicher keine Klasse.
Gruß
xaromz
Gruß
xaromz