Overriding class in Delphi - A Design Pattern Question

113 views Asked by At

I'm currently working with a three-tiered hierarchy of Delphi TFrame objects:

  • TItemsFrame - A base TFrame defining a scrolling area with items.
  • TDrawItemsFrame - A TFrame that overrides TItemsFrame to define how the items are drawn.
  • TFullPage - Another TFrame that extends TDrawItemsFrame, adding header and footer sections.

The twist comes when I have two different projects that each require a unique way to draw the items, without modifying any descendants of TDrawItemsFrame.

I imagine the solution would look something like this:

  • Main project: type TItemsFrame = Class(TFrame)
  • Main project: type TDrawItemsFrame = Class(TItemsFrame)
  • Main project: type TFullPage = Class({$I AncestorClass.inc})
  • Main project: type TOtherFullPage = Class({$I AncestorClass.inc}) and so on

Then for the individual projects:

  • Project A: Define type TCustom_A_DrawItemsFrame = Class(TDrawItemsFrame) and set AncestorClass.inc to TCustom_A_DrawItemsFrame.
  • Project B: Define type TCustom_B_DrawItemsFrame = Class(TDrawItemsFrame) and set AncestorClass.inc to TCustom_B_DrawItemsFrame.

My question is, does this approach align with good Delphi practices, or is there a better Strategy Pattern I should consider to solve this problem? Any insights would be greatly appreciated!

1

There are 1 answers

0
Trome On

you can do it like Some VCL Components : on the TItemsFrame class expose an event OnDrawItem with all the parameter that can be modified for every item.

Example :

TItemsFrame = class(TFrame)
...
  fExternalDrawEvent : reference to procedure (out OItemColor : TColor);
                       // or procedure (out OItemColor : TColor) of object
  procedure DoExtDraw(out OItemColor : TColor);
...
public
...
  property OnDrawItem : TExternalDrawEvent read : fExternalDrawEvent write fExternalDrawEvent ;
...
end;

TItemsFrame.DoExtDraw(out OItemColor : TColor);
begin
  if assigned(fExternalDrawEvent) then
  begin
    fExternalDrawEvent(OItemColor); 
  end;
end;

procedure TItemsFrame.DrawingItems ;
var 
  lItemColor : TColor;
begin
  ...
  if fExternalDrwaingEnabled then
  begin
    DoExtDraw(lItemColor );
  end;
  ...
  Item[i].color := lItemColor ;
  ...
end;

for example the first program :

procedure 
var 
  lExampleFrame : TFullPage;
begin
// Create
  lExampleFrame.OnDrawItem(
    procedure (out OItemColor : TColor) 
    begin
      OItemColor := clred; 
    end
  );  

end;

for example the second program :

procedure 
var 
  lExampleFrame : TFullPage;
begin
// Create
  lExampleFrame.OnDrawItem(
    procedure (out OItemColor : TColor) 
    begin
      OItemColor := clBlue; 
    end
  );  

end;