AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Algorithmen, Datenstrukturen und Klassendesign Zur Laufzeit erzeugte Klassen mit Parametern versorgen

Zur Laufzeit erzeugte Klassen mit Parametern versorgen

Ein Thema von Jumpy · begonnen am 8. Mär 2012 · letzter Beitrag vom 9. Mär 2012
Antwort Antwort
Seite 1 von 2  1 2   
Jumpy

Registriert seit: 9. Dez 2010
Ort: Mönchengladbach
1.717 Beiträge
 
Delphi 6 Enterprise
 
#1

Zur Laufzeit erzeugte Klassen mit Parametern versorgen

  Alt 8. Mär 2012, 11:34
Hallo und guten morgen erstmal...

Mir fehlen mal wieder die richtigen Schlagworte/Konzepte/Grundlagen:

Ich möchte zur Laufzeit verschiedene Klassen (eigentl. Objekte, klar) erzeugen. Welche das sind soll von außen gesteuert werden, z.B. über eine Konfig-Tabelle. Ich lese mir dazu nochmal was zu Klassenfabriken durch und denke, dass ich das hin kriege.
Die Klassen werden von einer gemeinsamen Basisklasse erben oder dasselbe Interface implementieren, so dass ich mit ihnen weiterarbeiten kann (ggf. weiterhin ohne zu wissen, welche konkrete Klasse ich gerade habe).

Das Problem ist, dass die Klassen zum arbeiten unterschiedliche Angaben brauchen und die Frage ist: wie krieg ich die denen übermittelt?

Ich könnte in der Konfig-Datei neben dem Klassennamen einen Parameterstring speichern und der Klasse nach der Erzeugung übergeben. In einer öffentl. Prozedur oder Property (ginge das?), die über das Interface bekannt wäre. Die jeweilige Implementation der Funktion in der konkreten Klasse, muss dann dafür sorgen, das der Parameterstring korrekt zerlegt wird.

Oder ich speichere in der Konfig-Datei zusätzlich eine ID und gebe die bei der Klassenerzeugung mit an. Zu jeder Klasse könnte es dann eine (immer anders aufgebaute) Tabelle geben, aus der sich die Klasse selber über die ID, ihre Parameter holt. (Wäre dann sowas wie ein Mini-ORM, oder?).

Oder ein ganz anderer Ansatz oder Konzept, dass ich nicht kenne, vllt? Ich hab dafür Delphi2010 zur verfügung, also ginge auch was mit RTTI, obwohl ich da bisher kaum Ahnung vonhab.
Ralph
  Mit Zitat antworten Zitat
Panthrax

Registriert seit: 18. Feb 2005
286 Beiträge
 
Delphi 2010 Enterprise
 
#2

AW: Zur Laufzeit erzeugte Klassen mit Parametern versorgen

  Alt 8. Mär 2012, 13:28
Etwa so?

Delphi-Quellcode:
type
  IMeineSchnittstelle = interface

  end;

  TMeineKlasse = class(TInterfacedObject, IMeineSchnittstelle)
  strict protected
    function GetValueAsString: String; virtual; abstract;

  public
    property ValueAsString: String read GetValueAsString;

    constructor Create(const ParamStr: String); virtual; abstract;
  end;

  TMeineKlasseClass = class of TMeineKlasse;

  TNativeIntNachkomme = class(TMeineKlasse)
  strict private
    FValue: NativeInt;

  strict protected
    function GetValueAsString: String; override;

  public
    constructor Create(const ParamStr: String); override;
  end;

  TStringNachkomme = class(TMeineKlasse)
  strict private
    FValue: String;

  strict protected
    function GetValueAsString: String; override;

  public
    constructor Create(const ParamStr: String); override;
  end;
Das erzeugen der Klasse ist eigentlich ganz einfach, solange man erst einmal die Klasse hat. Hier eine "Fabrikroutine":
Delphi-Quellcode:
function CreateMeineKlasse(const Cls: TMeineKlasseClass;
  const ParamStr: String): TMeineKlasse; overload;
begin
  Result := Cls.Create(ParamStr);
end;
Im Anhand findest Du eine Konsolenanwendung, die das demonstriert. Die Möglichkeit es über die Schnittstelle zu machen, nutze ich im Beispiel aber nicht.
Angehängte Dateien
Dateityp: pas Thema166980.dpr.pas (2,9 KB, 11x aufgerufen)
"Es gibt keine schlimmere Lüge als die Wahrheit, die von denen, die sie hören, missverstanden wird."
  Mit Zitat antworten Zitat
Jumpy

Registriert seit: 9. Dez 2010
Ort: Mönchengladbach
1.717 Beiträge
 
Delphi 6 Enterprise
 
#3

AW: Zur Laufzeit erzeugte Klassen mit Parametern versorgen

  Alt 8. Mär 2012, 14:04
Bevor ich mir die Demo anguck, schonmal schnell gefragt:

Was genau macht eigentlich:
TMeineKlasseClass = class of TMeineKlasse;

Und woher weiß die Fabrikroutine, ob sie jetzt einen StringNachkommen oder einen IntNachkommen erzeugen soll?
Ziehe die Frage nach durchlesen der Demo zurück.
Ralph

Geändert von Jumpy ( 8. Mär 2012 um 14:11 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Aphton
Aphton

Registriert seit: 31. Mai 2009
1.198 Beiträge
 
Turbo Delphi für Win32
 
#4

AW: Zur Laufzeit erzeugte Klassen mit Parametern versorgen

  Alt 8. Mär 2012, 16:04
Damit kannst du solche Spielchen treiben
Delphi-Quellcode:
const
  meineRegistriertenKlassen: array[0..3] of TMeineKlasseClass = (TKlasse1, TKlasse2, TKlasse3, TKlasse4);
{..}
  meineInstanz := meineRegistriertenKlassen[klassenIndex].Create;
Beispiele findest du bei den Grafikkomponenten.
Der hat intern auch eine Liste (Array), in der für jedes Format (bmp, jpg, png, ...) eine Klasse drinnen steht. Willst du nun ein Bild laden, so erkennt der, welcher "Loader" notwendig ist, instanziert diesen und lädt anschließend.
Fein ist es auch, dass man ganz einfach seine eigenen Formate registrieren kann usw. (ich drifte ab).
Du solltest es verstanden haben!
das Erkennen beginnt, wenn der Erkennende vom zu Erkennenden Abstand nimmt
MfG

Geändert von Aphton ( 8. Mär 2012 um 16:07 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
40.480 Beiträge
 
Delphi 11 Alexandria
 
#5

AW: Zur Laufzeit erzeugte Klassen mit Parametern versorgen

  Alt 8. Mär 2012, 16:34
Oder da wo die Grafikklassen bei TPicture angemeldet sind, mit ihren Dateiendungen, so daß TImage/TPicture sich dann die passende Klasse zur Dateiendung raussuchen kann.

Oder TComponent der VCL, wo die VCL alle TComponent-Nachfahren problemlos erstellen und befüllen kann.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list
  Mit Zitat antworten Zitat
shmia

Registriert seit: 2. Mär 2004
5.508 Beiträge
 
Delphi 5 Professional
 
#6

AW: Zur Laufzeit erzeugte Klassen mit Parametern versorgen

  Alt 8. Mär 2012, 18:37
Vielleicht suchst du auch das Builder-Design-Pattern.
Ein Builder ist eine Klasse, die ein oder mehrere Objekte in mehreren Schritten erstellen kann.

Kleines Beispiel:
Delphi-Quellcode:
TCarBuilder = class(TObject)
public
  procedure AddChassis(lenght,width:integer);
  procedure AddEngine(horsepower:double);
  procedure SetColor(color:TColor);
  procedure AddTyres(diameter:integer);

  function GetCar:TCar;
end;

var
  builder : TCarBuilder;
  newcar : TCar;
begin
  builder := TCarBuilder.Create;
  // Schrittweise zusammenbauen
  builder.AddChassis(460, 165);
  builder.AddEngine(210.0 {PS});
  builder.SetColor(clBlack);
  builder.AddTyres(19 {Zoll});
  // und Ergebnis abholen
  newcar := builder.GetCar;
Ein Builder kann natürlich auch durch Konfigurationsdateien gesteuert werden.
Andreas
  Mit Zitat antworten Zitat
Jumpy

Registriert seit: 9. Dez 2010
Ort: Mönchengladbach
1.717 Beiträge
 
Delphi 6 Enterprise
 
#7

AW: Zur Laufzeit erzeugte Klassen mit Parametern versorgen

  Alt 9. Mär 2012, 12:43
Ich wiederhol nochmal eine Frage zum Grundverständnis:
Was genau macht eigentlich:
TMeineKlasseClass = class of TMeineKlasse;
Generell dieses "class of"? TMeineKlasse ist doch schon die Klasse, die ich brauche. Was ist dann TMeineKlasseClass?


Und dann noch eine Frage zu Fabriken (da ich durch die ganzen "verweiste Referenzen"-Threads der letzten Zeit etwas verwirrt bin). Eine Fabrik erzeugt ein Objekt und "gibt dass nach aussen an eine andere Klasse weiter" (Wenn man so will an den Kunden der Fabrik). Jetzt gibt es doch 2 Referenzen auf das Objekt. Wer gibt das Objekt später wieder frei und wie erfährt der andere davon?

@shmia: Das passt in dem Fall den ich im Kopf habe, glaub ich erstmal nicht, da es doch schon verschiedene Klassen sind, die die Fabrik erstellen soll und nicht eine Klasse mit unterschiedlichen Werten, wie der Builder das mMn macht.
Ralph

Geändert von Jumpy ( 9. Mär 2012 um 12:47 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
40.480 Beiträge
 
Delphi 11 Alexandria
 
#8

AW: Zur Laufzeit erzeugte Klassen mit Parametern versorgen

  Alt 9. Mär 2012, 12:59
Was genau macht eigentlich:
TMeineKlasseClass = class of TMeineKlasse;
Generell dieses "class of"? TMeineKlasse ist doch schon die Klasse, die ich brauche. Was ist dann TMeineKlasseClass?
Delphi-Quellcode:
var
  Objekt: TMeineKlasse;
  Klasse: TMeineKlasseClass;
Eine TMeineKlasse-Variable kann eine instantiierte Objektinstanz dieser Klasse oder deren Nachfahren aufnehmen,
während TMeineKlasseClass die Klasse selber aufnehmen kann, oder einen ihrer Nachfahren.
Delphi-Quellcode:
if X then
  Klasse := TMeineKlasse
else
  Klasse := TMeineNachfahrKlasse;

Objekt := Klasse.Create;

Klasse.Klassenprozedur(123); // ausführen einer Class Procedure/Function dieses Types aus (natürlich praktisch, wenn das ding dann virtual wäre)
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list
  Mit Zitat antworten Zitat
Benutzerbild von DeddyH
DeddyH

Registriert seit: 17. Sep 2006
Ort: Barchfeld
27.455 Beiträge
 
Delphi 11 Alexandria
 
#9

AW: Zur Laufzeit erzeugte Klassen mit Parametern versorgen

  Alt 9. Mär 2012, 13:02
Durch das class off kannst Du Dir einen "Oberbegriff" für die Art der zu erstellenden Objektklasse definieren. Brauchst Du eine Instanz von TDings, übergibst Du TDings als Parameter, soll es TBums sein, dann eben TBums. Ohne das class of müsstest Du ja für jeden Typ eine überladene Methode schreiben, so kannst Du die Klasse einfach festlegen.
Detlef
"Ich habe Angst vor dem Tag, an dem die Technologie unsere menschlichen Interaktionen übertrumpft. Die Welt wird eine Generation von Idioten bekommen." (Albert Einstein)
Dieser Tag ist längst gekommen
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.289 Beiträge
 
Delphi 10.4 Sydney
 
#10

AW: Zur Laufzeit erzeugte Klassen mit Parametern versorgen

  Alt 9. Mär 2012, 14:11
Und dann noch eine Frage zu Fabriken (da ich durch die ganzen "verweiste Referenzen"-Threads der letzten Zeit etwas verwirrt bin). Eine Fabrik erzeugt ein Objekt und "gibt dass nach aussen an eine andere Klasse weiter" (Wenn man so will an den Kunden der Fabrik). Jetzt gibt es doch 2 Referenzen auf das Objekt. Wer gibt das Objekt später wieder frei und wie erfährt der andere davon?
Ich denke mal, dass Du Dich hierauf beziehst:
- http://www.delphipraxis.net/166899-i...eferenzen.html
- http://www.delphipraxis.net/159095-r...e-objekte.html

Grundsätzlich sehe ich mehrere Möglichkeiten:

1) Du verwaltest keine festen Referenzen auf ein bestimmtes Objekt, sondern nur eine Id. Bei Bedarf forderst Du bei einem "Broker" anhand der ID das entsprechende Objekt ab und bekommst dieses oder nil geliefert. In deiner aktuellen Methode kannst Du dann mit dem Rückgabewert arbeiten.
Der "Broker" kann dann die Objekte eine bestimmte Zeit zwischenspeichern und irgendwann wieder verwerfen.
Die Objekte müssen sich also nicht dauerhaft im Speicher befinden sondern können bei Bedarf neu erzeugt und mit Daten aus einer Datenbank "befüllt" werden (ORM).
Da Du keine festen Referenzen verwaltest, brauchst Du auch keine Referenzen auf nil setzen, wenn Du ein Objekt auflöst.

2) Eine etwas halbherzigere Lösung wäre, alle erzeugten Objekte (einer bestimmten Sorte) in einer Liste zu speichern und beim Auflösen wieder daraus zu entfernen. Dann kann man bei jedem Zugriff auf eine Objektreferenz prüfen, ob sich das Objekt noch in der "Gültigkeitsliste" befindet. Statt Assign(o) könnte man sich eine Funktion Exist(o) deklarieren.

3) Wenn Du mit reinen Objekten arbeitest und diese gegenseitig referenzierst, dann kannst Du mit einem Observer-Pattern referenzierende Objekte bei referenzierten Objekten anmelden (in einer Liste eintragen). Wird das referenzierte Objekt aufgelöst, werden alle referenzierenden Objekte zuvor darüber unterrichtet und setzen die entsprechende Eigenschaft auf nil. Das muss man jedoch alles von Hand regeln und dafür entsprechende Listen und Methoden einführen.

4) Anstatt Objekte kann man Interfaces verwenden, welche einige Vorteile haben allerdings auch einigen Mehraufwand mit sich bringen. Interfaces werden sozusagen automatisch überwacht und wenn kein Interface auf ein Objekt mehr verwendet wird, wird das Objekt freigegeben (jedenfalls in Delphi).

EDIT: Ach so, und die Lösung von Thom unter dem ersten Link, die die Ansätze 3 + 4 miteinander verbindet.
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)

Geändert von stahli ( 9. Mär 2012 um 14:32 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2   

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:30 Uhr.
Powered by vBulletin® Copyright ©2000 - 2022, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2021 by Daniel R. Wolf