Delphi - proxy template - interface problem

Hi I am trying to make design patterns in Delphi, and since I could not find the reference material that I like in Delphi, I am converting the patterns that I have in the Ortilly C # 3.0 Design Patterns book. But it's not a problem. I created a proxy template from this book, but there are some concepts of Delphi interfaces, constructors, and destructors, as well as the total lifetime and behavior of the object, which I apparently do not understand. First I will send my code:

unit Unit2;  

interface  

uses
  SysUtils;

type
  ISubject = interface
  ['{78E26A3C-A657-4327-93CB-F3EB175AF85A}']
  function Request(): string;
end;

  TSubject = class
  public
    function Request(): string;
    constructor Create();
  end;

  TProxy = class (TInterfacedObject, ISubject)
  private
    FSubject: TSubject;
  public
    function Request(): String;
    destructor Destroy(); override;
  end;

  TProtectionProxy = class (TInterfacedObject, ISubject)
  private
    FSubject: TSubject;
    FPassword: String;
  public
    constructor Create();
    destructor Destroy(); override;
    function Authenticate(supplied: String): String;
    function Request(): String;
  end;

implementation

{ TSubjectAccessor.TProxy }

destructor TProxy.Destroy;
begin
  if Assigned(Self.FSubject) then
    FreeAndNil(Self.FSubject);
  inherited;
end;

function TProxy.Request: String;
begin
  if not Assigned(Self.FSubject) then begin
    WriteLn('Subject Inactive');
    Self.FSubject := TSubject.Create();
  end;
  WriteLn('Subject active');
  Result := 'Proxy: Call to ' + Self.FSubject.Request();
end;

{ TSubject }

constructor TSubject.Create;
begin
  inherited;
end;

function TSubject.Request: string;
begin
  Result := 'Subject Request Choose left door' + #10;
end;

{ TProtectionProxy }

function TProtectionProxy.Authenticate(supplied: String): String;
begin
  if (supplied <> Self.FPassword) then begin
    Result := 'Protection proxy: No Access!';
  end else begin
    Self.FSubject := TSubject.Create();
    Result := 'Protection Proxy: Authenticated';
  end;
end;

constructor TProtectionProxy.Create;
begin
  Self.FPassword := 'Abracadabra';
end;

destructor TProtectionProxy.Destroy;
begin
  if Assigned(Self.FSubject) then
    FreeAndNil(Self.FSubject);
  inherited;
end;

function TProtectionProxy.Request: String;
begin
  if not Assigned(Self.FSubject) then begin
    Result := 'Protection Proxy: Authenticate first!';
  end else begin
    Result := 'Protection Proxy: Call to ' + Self.FSubject.Request();
  end;
end;

end.

These are the interfaces and classes used in the template. Next, this is the code that uses these types:

program Structural.Proxy.Pattern;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  Unit2 in 'Unit2.pas';

var
  subject: ISubject;

begin
  ReportMemoryLeaksOnShutdown := DebugHook <> 0;

  try
    WriteLn('Proxy Pattern' +  #10);

    try
      subject := TProxy.Create();
      WriteLn(subject.Request());
      WriteLn(subject.Request());

      subject := TProtectionProxy.Create();
      WriteLn(subject.Request());
      WriteLn(TProtectionProxy(subject).Authenticate('Secret'));
      WriteLn(TProtectionProxy(subject).Authenticate('Abracadabra'));
      WriteLn(subject.Request());

      ReadLn;      
    finally

    end;

  except
    on E:Exception do
      Writeln(E.Classname, ': ', E.Message);
  end;
end.

? , TProtectionProxy, TProxy. TProtectionProxy ( "Abracadabra" ) , FPassword , ? . , ? TProtectionProxy (subject) , , , ( TProtectionProxy) - ( ...)? - FSubject. ? , , , TProtectionProxy?

, , , Delphi OOP , .

.


, . .

unit Unit2;

interface

uses
  SysUtils;

type
  ISubject = interface
  ['{78E26A3C-A657-4327-93CB-F3EB175AF85A}']
    function Request(): string;
  end;

  IProtected = interface
  ['{928BA576-0D8D-47FE-9301-DA3D8F9639AF}']
    function Authenticate(supplied: string): String;
  end;

  TSubject = class
  public
    function Request(): string;
  end;

  TProxy = class (TInterfacedObject, ISubject)
  private
    FSubject: TSubject;
  public
    function Request(): String;
    destructor Destroy(); override;
  end;

  TProtectionProxy = class (TInterfacedObject, ISubject, IProtected)
  private
    FSubject: TSubject;
    const FPassword: String =  'Abracadabra';
  public
    destructor Destroy(); override;
    function Authenticate(supplied: String): String;
    function Request(): String;
  end;

implementation

{ TSubjectAccessor.TProxy }

destructor TProxy.Destroy;
begin
  if Assigned(FSubject) then
    FreeAndNil(FSubject);
  inherited;
end;

function TProxy.Request: String;
begin
  if not Assigned(FSubject) then begin
    WriteLn('Subject Inactive');
    FSubject := TSubject.Create();
  end;
  WriteLn('Subject active');
  Result := 'Proxy: Call to ' + FSubject.Request();
end;

{ TSubject }

function TSubject.Request: string;
begin
  Result := 'Subject Request Choose left door' + #10;
end;

{ TProtectionProxy }

function TProtectionProxy.Authenticate(supplied: String): String;
begin
  if (supplied <> FPassword) then begin
    Result := 'Protection proxy: No Access!';
  end else begin
    FSubject := TSubject.Create();
    Result := 'Protection Proxy: Authenticated';
  end;
end;

destructor TProtectionProxy.Destroy;
begin
  if Assigned(FSubject) then
    FreeAndNil(FSubject);
  inherited;
end;

function TProtectionProxy.Request: String;
begin
  if not Assigned(FSubject) then begin
    Result := 'Protection Proxy: Authenticate first!';
  end else begin
    Result := 'Protection Proxy: Call to ' + FSubject.Request();
  end;
end;

end.

:

program Structural.Proxy.Pattern;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  Unit2 in 'Unit2.pas';

var
  subject: ISubject;
  protect: IProtected;

begin
  ReportMemoryLeaksOnShutdown := DebugHook <> 0;

  try
    WriteLn('Proxy Pattern' +  #10);

    try
      subject := TProxy.Create();
      WriteLn(subject.Request());
      WriteLn(subject.Request());

      subject := nil;
      subject := TProtectionProxy.Create();
      WriteLn(subject.Request());
      if Supports(subject, IProtected, protect) then begin
        WriteLn(protect.Authenticate('Secret'));
        WriteLn(protect.Authenticate('Abracadabra'));
      end;
      WriteLn(subject.Request());
      ReadLn;      
    finally

    end;

  except
    on E:Exception do
      Writeln(E.Classname, ': ', E.Message);
  end;
end.

, . TInrefacedObject, ? , , ?

http://delphipatterns.blog.com/2011/02/22/proxy-2/

+5
2

, Delphi . , , Delphi XE () :

Proxy Pattern

Subject Inactive
Subject active
Proxy: Call to Subject Request Choose left door

Subject active
Proxy: Call to Subject Request Choose left door

Protection Proxy: Authenticate first!
Protection proxy: No Access!
Protection Proxy: Authenticated
Protection Proxy: Call to Subject Request Choose left door

:

Project2.dpr.25: WriteLn(TProtectionProxy(subject).Authenticate('Secret'));
004122C2 A1788E4100       mov eax,[$00418e78]
004122C7 8B154CF84000     mov edx,[$0040f84c]
004122CD E8E22BFFFF       call @SafeIntfAsClass
004122D2 8D4DE0           lea ecx,[ebp-$20]
004122D5 BA38244100       mov edx,$00412438
004122DA E875D9FFFF       call TProtectionProxy.Authenticate
004122DF 8B55E0           mov edx,[ebp-$20]
004122E2 A1EC3C4100       mov eax,[$00413cec]
004122E7 E8BC24FFFF       call @Write0UString
004122EC E82F25FFFF       call @WriteLn
004122F1 E82A1CFFFF       call @_IOTest

, SafeIntfAsClass, ISubject , ISubject. TProtectionProxy.Authenticate () Self.

Delphi, :

var
  subject: ISubject;
begin
...
      subject := TProtectionProxy.Create();
      WriteLn(subject.Request());
      WriteLn(TProtectionProxy(subject).Authenticate('Secret'));

Delphi . , subject TProtectionProxy.Authenticate.

, TProtectionProxy.Authenticate - , , . TProtectionProxy.Authenticate . TProtectionProxy, ISubject.

delphi - :

type
  IProtection = interface
    ['{ACA182BF-7675-4346-BDE4-9D47CA4ADBCA}']
    function Authenticate(supplied: String): String;
  end;
...
  TProtectionProxy = class (TInterfacedObject, ISubject, IProtection)
...

var
  subject: ISubject;
  protection: IProtection;
...
      subject := TProtectionProxy.Create();
      WriteLn(subject.Request());
      if Supports(subject, IProtection, protection) then begin
        WriteLn(protection.Authenticate('Secret'));
        WriteLn(protection.Authenticate('Abracadabra'));
      end else
        WriteLn('IProtection not supported!');
      WriteLn(subject.Request());

, . , , - ( , ). Delphi XE , , .

+5

?

  • . , Delphi.

, TProtectionProxy, TProxy.

  • - ? .

TProxy, subject nil:

  subject := TProxy.Create();
  WriteLn(subject.Request());
  WriteLn(subject.Request());

  subject := nil;
  subject := TProtectionProxy.Create();
  ..

TProtectionProxy ( "Abracadabra" ) , FPassword , ? .

  • . FPassword , .

, ?

  • . nil readln:

    : = nil; ReadLn;

TProtectionProxy (subject) , , , ( TProtectionProxy) - ( ...)?

  • , . TProtectionProxy (subject) (subject as TProtectionProxy) .

- FSubject. ?

  • , FSubject .

, , , TProtectionProxy?

  • , FPassword , .

FPassword, :

  TProtectionProxy = class (TInterfacedObject, ISubject)
  private
    FSubject: TSubject;
    const FPassword: String = 'Abracadabra';
  public
    constructor Create();
    destructor Destroy(); override;
    function Authenticate(supplied: String): String;
    function Request(): String;
  end;

Self - .

+2

All Articles