Professional Documents
Culture Documents
D1 From Interfaces To SOLID
D1 From Interfaces To SOLID
Arnaud Bouchez
June 2015
From Interfaces to SOLID
Delphi and interfaces
SOLID design principles
Weak pointers
Dependency Injection, stubs and mocks
Declaring an interface
type
ICalculator = interface(IInvokable)
['{9A60C8ED-CEB2-4E09-87D4-4A16F496E5FE}']
/// add two signed 32 bit integers
function Add(n1,n2: integer): integer;
end;
Implementing an interface
type
TServiceCalculator = class(TInterfacedObject, ICalculator)
protected
fBulk: string;
public
function Add(n1,n2: integer): integer;
procedure SetBulk(const aValue: string);
end;
Using an interface
function MyAdd(a,b: integer): integer;
var Calculator: ICalculator;
begin
Calculator := TServiceCalculator.Create;
result := Calculator.Add(a,b);
end;
Strong typing
The variable defines a behavior (contract)
Path to abstraction
Using an interface
function MyAdd(a,b: integer): integer;
function MyAdd(a,b: integer): integer; var Calculator: TServiceCalculator;
var Calculator: ICalculator; begin
begin Calculator := TServiceCalculator.Create;
Calculator := TServiceCalculator.Create; try
result := Calculator.Add(a,b); result := Calculator.Add(a,b);
end; finally
Calculator.Free;
end;
end;
Strong typing
The variable defines a behavior (contract)
Path to abstraction
Automatic try..finally
Automatic try..finally
Compiler generates function MyAdd(a,b: integer): integer;
var Calculator: TServiceCalculator;
some hidden code… begin
Calculator := nil;
Calculator := TServiceCalculator.Create;
function MyAdd(a,b: integer): integer; try
var Calculator: ICalculator; Calculator.FRefCount := 1;
begin result := Calculator.Add(a,b);
Calculator := TServiceCalculator.Create; finally
result := Calculator.Add(a,b); dec(Calculator.FRefCount);
end; if Calculator.FRefCount=0 then
Calculator.Free;
end;
end;
Open/closed principle
IChild = interface
procedure SetParent(const Value: IParent);
function GetParent: IParent;
property Parent: IParent read GetParent write SetParent;
end;
with TLoginController.Create(UserRepository,SmsSender) do
try
ForgotMyPassword('toto');
finally
Free;
end;
end;