Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Viele Objekttypen handlen? (https://www.delphipraxis.net/48874-viele-objekttypen-handlen.html)

Treffnix 1. Jul 2005 17:40


Viele Objekttypen handlen?
 
Hallo,

ich steh gerade ziemlich aufm Schlauch. Ich habe viele Ableitungen ( und es können noch mehr werden ) von einem Basistypen, die verschiedene Geräte handlen. Initial muss ich nun erstmal herausfinden um welches Gerät es sich handelt. Die Ableitungen haben dazu eine Methode, die überprüft ob es sich um ihr zugehöriges Gerät handelt.
Dazu müsste ich die Ableitungen quasi in Schleife durchlaufen. Und da liegt mein Problem. Keine Ahnung obs daran liegt, dass das Wochenende vor der Tür steht, aber ich finde keine annehmbare Lösung.

Mal ein bissl Pseudocode...
Im Endeffekt soll die Funktion folgendes machen:

Delphi-Quellcode:
If Ableitung1.bistdudas( Gerät ) Then
  Ableitung1.Create( Gerät );
Ableitung2.bistdudas( Gerät ) Then
  Ableitung1.Create( Gerät );
Ableitung3.bistdudas( Gerät )Then
  Ableitung1.Create( Gerät );
Ableitung4.bistdudas( Gerät ) Then
  Ableitung1.Create( Gerät );
usw...
Da das aber ziemlich lang wird und ich nicht für jede neue Ableitung, die in Zukunft hinzukommen könnte jedesmal die Funktion erweitern möchte, würde ich das lieber in der Art machen

Delphi-Quellcode:
For i:= 0 to Ableitungscount -1 Do
  If Ableitung[i]( Basisobjekt ).bistdudas then
    Ableitung[i].Create
Erleuchtet mich

Dani 1. Jul 2005 18:23

Re: Viele Objekttypen handlen?
 
Hi,

Ich hoff mal ich hab auch verstanden worum es geht :roll:. Ich würde es so lösen:

Delphi-Quellcode:
type
  TDeviceType = (Device1, Device2);

  TDeviceClass = class of TBasicDevice;

  TBasicDevice = class(TPersistent)
  public
   class function GetDeviceClass(DeviceType: TDeviceType): TDeviceClass;
  end;

  TDevice1 = class(TBasicDevice);
   {...}
  TDevice2 = class(TBasicDevice);
   {...}

implementation

{...}

{ TBasicDevice }

class function TBasicDevice.GetDeviceClass(
  DeviceType: TDeviceType): TDeviceClass;
begin
 case DeviceType of
  Device1: Result := TDevice1;
  Device2: Result := TDevice2;
  else
   Result := nil;
 end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var DeviceClass: TDeviceClass;
    SomeDevice: TBasicDevice;
begin
 DeviceClass := TBasicDevice.GetDeviceClass(Device1);
 If DeviceClass <> nil then
  SomeDevice := DeviceClass.Create;
end;

{...}
Wenn du eine neuen Nachkommen hinzufügst, muss die GetDeviceClass Methode aktualisiert werden, aber ich sehe auch keinen Weg, das zu vermeiden, weil du eine Geräte-Klasse aufgrund einer Information (in deinem Pseudocode das "Gerät") identifizieren willst, die selbst keine Klasse ist.

Edit: rethorische Verbrechen entfernt.

Robert_G 1. Jul 2005 18:50

Re: Viele Objekttypen handlen?
 
Zitat:

Zitat von Dani
Wenn du eine neuen Nachkommen hinzufügst, muss die GetDeviceClass Methode aktualisiert werden, aber ich sehe auch keinen Weg, das zu vermeiden

Ich schon ;)
Delphi-Quellcode:
uses
   uDevice;

type
   TBaseDings = class
   private
      fDevice: TDevice;
   protected
      class function MatchesDevice(const aDevice: TDevice): Boolean; virtual; abstract;
      class procedure Register;
   public
      property Device: TDevice read fDevice;
      class function CreateMatchingDings(const aDevice: TDevice): TBaseDings;
      constructor Create(const aDevice: TDevice); virtual;
   end;

   TBaseDingsClass = class of TBaseDings;

implementation
uses
   Contnrs;
var
   ClassList           : TClassList;

constructor TBaseDings.Create(const aDevice: TDevice);
begin
   fDevice := aDevice;
end;

class function TBaseDings.CreateMatchingDings(const aDevice: TDevice): TBaseDings;
var
   i                   : Integer;
   BaseDingsClass      : TBaseDingsClass;
begin
   result := nil;
   for i := 0 to ClassList.Count - 1 do
   begin
      BaseDingsClass := TBaseDingsClass(ClassList[i]);
      if BaseDingsClass.MatchesDevice(aDevice) then
      begin
         result := BaseDingsClass.Create(aDevice);
         Break;
      end;
   end;
end;

class procedure TBaseDings.Register;
begin
   if ClassList.IndexOf(Self) = -1 then
      ClassList.Add(Self);
end;


initialization
   ClassList := TClassList.Create();
finalization
   ClassList.Free();
end.
und nun für jedes nur noch Gerät sowas:

Delphi-Quellcode:
uses
   uBaseDings,
   uDevice;

type
   TDings1Device = class(TDevice)
      // mööp
   end;


   TDings1 = class(TBaseDings)
   protected
      class function MatchesDevice(const aDevice: TDevice): Boolean; override;
   public
      constructor Create(const aDevice: TDevice); override;

   end;
implementation

{ TDings1 }

constructor TDings1.Create(const aDevice: TDevice);
begin
end;

class function TDings1.MatchesDevice(const aDevice: TDevice): Boolean;
begin
   Result := aDevice is TDings1Device;
end;

initialization
   // In die ClassList registrieren
   TDings1.Register;
end.

Wobei ich in dem Schritt zwichen BaseDings und Dings1 noch die eigentliche Basisklasse setzen würde, die die grundlegende Funktionalität (virtuell) bereitstellt. ;)

Treffnix 1. Jul 2005 19:28

Re: Viele Objekttypen handlen?
 
Das "Match" is zwar insgesamt etwas aufwändiger als das es mit nem is getan wäre, aber das sind schonmal 2 Richtungen, an die ich nicht gedacht hätte. Allerdings krieg ich bei beiden Probleme, sollte die Forderung kommen, die Geräte dynamisch aus DLLs zu laden, aber das ist noch nicht sicher und ich hatte ja auch nichts davon gesagt. Nu is erstmal Wochenende. Werd am Montag mal schauen, ob ich damit ne akzeptable Lösung auf die Reihe kriege. Vielleicht hab ich dann ja auch nicht mehr son Brett vorm Kopf. :wall:

Auf jeden Fall danke erstmal euch beiden!


Alle Zeitangaben in WEZ +1. Es ist jetzt 19:52 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 by Thomas Breitkreuz