Recent

Author Topic: Interface delegation [SOLVED]  (Read 2691 times)

pascal111

  • Sr. Member
  • ****
  • Posts: 292
  • Un trabajo en equipo para programas serias.
Re: Interface delegation
« Reply #15 on: May 29, 2021, 06:01:53 pm »
ما معنى الـ  Interface delegation أو ما هي فكرته أو فائدته فلقد ترجمتُ هذه الوثيقة https://www.freepascal.org/docs-html/current/ref/refse48.html#x101-1250007.5 ولم تصلني الفكرة بعد؟

google translate:

"What is the meaning of Interface delegation or what is its idea or its usefulness I have translated this document https://www.freepascal.org/docs-html/current/ref/refse48.html#x101-1250007.5 The idea did not reach me yet?"

Interface delegation is used if you want a concrete class to support several interfaces but you do not want to implement all interfaces in one class because  it may cause class become complex and do many things. To make class simple and avoid doing many things, you delegate to an external implementation.

example scenario: you want to make a pencil case product which has ability to charge your phone.  This multifunctional product can act as IPencilCase or as a IPowerBank interface. You can make all powerbank electronic circuitry+batteries in this product all by yourself or you can just buy third party ready-made powerbank and embed it in pencil case (delegate powerbank functionality to external powerbank). The latter approach makes your pencil case simple in design while providing more features.

أظنّني فهمتُ الآن.

google translate:

"I guess I now understand."

lucamar

  • Hero Member
  • *****
  • Posts: 4178
Re: Interface delegation
« Reply #16 on: May 29, 2021, 06:03:05 pm »
I am sure know why interface and interface delegation can be useful:
- adding features from other's ready made classes
- for example COM objects (I know what COM object is)
- combining the features from interfaces

I do not see any usage to me now but I'm sure I will use it someday.

Note that some of those can be better accomplished by object composition, which is probably why interfaces are not that much used in Pascal: most times an abstract base class with a default implementation one (like e.g. TStrings/TStringList) and composition do the work nicely.
Turbo Pascal 3 CP/M - Amstrad PCW 8256 (512 KB !!!) :P
Lazarus/FPC 2.0.8/3.0.4 & 2.0.12/3.2.0 - 32/64 bits on:
(K|L|X)Ubuntu 12..18, Windows XP, 7, 10 and various DOSes.

jamie

  • Hero Member
  • *****
  • Posts: 4752
Re: Interface delegation [SOLVED]
« Reply #17 on: May 29, 2021, 06:22:37 pm »
I just put together a simple demo using a form as the show piece.

two buttons to show how you can select the interface instance you want to use where each procedure of the instance can have a totally different meaning...
Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls;
  9. {$interfaces corba}
  10. type
  11. IMyinterface = interface
  12.   procedure crap;
  13. end;
  14. IDelegate1 = Class(TinterfacedObject, ImyInterface)
  15.   procedure crap;
  16. end;
  17. IDelegate2 = Class(TInterfacedObject,ImyInterface)
  18.   procedure Crap;
  19. end;
  20.   { TForm1 }
  21.   TForm1 = class(TForm)
  22.     Button1: TButton;
  23.     Button2: TButton;
  24.     procedure Button1Click(Sender: TObject);
  25.     procedure Button2Click(Sender: TObject);
  26.     procedure FormCreate(Sender: TObject);
  27.     procedure FormDestroy(Sender: TObject);
  28.   private
  29.     fDelegator :ImyInterface;
  30.     fFirst :IDelegate1;
  31.     fSecond:IDelegate2;
  32.   public
  33.   end;
  34.  
  35. var
  36.   Form1: TForm1;
  37.  
  38. implementation
  39.  
  40. {$R *.lfm}
  41.  
  42. procedure TForm1.Button1Click(Sender: TObject);
  43. begin
  44.   fDelegator := ImyInterface(fFirst);
  45.   fdelegator.crap;
  46. end;
  47.  
  48. procedure TForm1.Button2Click(Sender: TObject);
  49. begin
  50.   fDelegator := ImyInterface(fSecond);
  51.   fdelegator.Crap;
  52. end;
  53.  
  54. procedure TForm1.FormCreate(Sender: TObject);
  55. begin
  56.  fFirst := Idelegate1.Create;
  57.  fsecond:= iDelegate2.Create;
  58. end;
  59.  
  60. procedure TForm1.FormDestroy(Sender: TObject);
  61. begin
  62.   fFirst.Free;
  63.   fSecond.Free;
  64. end;
  65.  
  66. Procedure IDelegate1.Crap;
  67. Begin
  68.   Form1.Caption := 'First Delegate used';
  69. End;
  70. Procedure IDelegate2.Crap;
  71. Begin
  72.   Form1.Caption := 'Second Delegate used';
  73. end;
  74. end.
  75.  
  76.  

here you can see where all you need to do is simply set a single delegator proxy field and all existing code that accesses the delegator needs not to know the difference.

 With this in mind, you can have a set of procedures all named the same all taking the same parameters but each method could have totally different code in them.
 
  Not to get confused with Generics where the types can be different but with the same code, here you can really mix it up!
The only true wisdom is knowing you know nothing

Handoko

  • Hero Member
  • *****
  • Posts: 4318
  • My goal: build my own game engine using Lazarus
Re: Interface delegation [SOLVED]
« Reply #18 on: May 29, 2021, 06:55:28 pm »
@lucamar

Understood.

What I'm thinking is, I ever wrote a simple pdf viewer for my friend so he can preview, print, browse and manage the pdf files into categories. I used ActiveXContainer to 'import' Acrobat Reader 7 into the program. That worked and still working good. I wondered how that can be done into Lazarus so I looked into the source code. It used a lot of interface 'things'. So, if I am good in using interface, I will able to, not simply 'import' but better control the objects.

@jamie

Thank you for the demo. It show the usage of interface delegation and the "like abstract method" you mentioned. It is a bit hard for me to 'digest' for now. I believe I can fully understand it when I really use it into my code in the future.

 

TinyPortal © 2005-2018