Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check class name

Tags:

class

delphi

I don't know OWNER object class name. So I must check everywhere in my codes like that :

if TObject(OWNER) is TFirstClass then begin
  TFirstClass(OWNER).FirstFunction;
  TFirstClass(OWNER).SecondFunction;
  ...
end else
if TObject(OWNER) is TSecondClass then begin
  TSecondClass(OWNER).FirstFunction;
  TSecondClass(OWNER).SecondFunction;
  ...
end;

Is there a better way? Because I must do this if condition in many place of the codes. All functions of TFirstClass and TSecondClass (which I have to run) are the same.

Note : I use Delphi 5.

like image 380
SimaWB Avatar asked Nov 29 '22 07:11

SimaWB


1 Answers

If you have no access to TFirstClass and TSecondClass, but still want to simplify your code, here's a way:

Create an adapter base class:

type
  TMyAdapter = class(TObject)
  public
    procedure FirstMethod; virtual; abstract;
    procedure SecondMethod; virtual; abstract;
  end;

Then create descendant classes TFirstClassAdapter and TSecondClassAdapter and give them each a private reference to the instance of TFirstClass or TSecondClass respectively. Add a constructor which sets this reference. Override the methods of the adapter classes, so that they call through to the adapted classes.

type
  TFirstClassAdapter = class(TMyAdapter)
  private
    fObject: TFirstClass;
  public
    constructor Create(AAdaptedObject: TFirstClass);

    procedure FirstMethod; override;
    procedure SecondMethod; override;
  end;

constructor TFirstClassAdapter.Create(AAdaptedObject: TFirstClass);
begin
  inherited Create;
  fObject := AAdaptedObject;
end;

procedure TFirstClassAdapter.FirstMethod;
begin
  fObject.FirstMethod;
end;

procedure TFirstClassAdapter.SecondMethod;
begin
  fObject.SecondMethod;
end;

Same for the other class. Now you only need to decide whether you create the adapter once and pass it around, or whether you make a function that you call everywhere you need it, and which will give you an adapter for your concrete class.

If you implement the adapter using interfaces, then you will not even need to manage the lifetime of the adapter yourself.

This way you can have the polymorphic behaviour that Ulrich gave in his answer, but without the need to change TFirstClass and TSecondClass.

like image 91
mghie Avatar answered Dec 09 '22 13:12

mghie