/
MVCBr.Patterns.Strategy.pas
102 lines (84 loc) · 2.26 KB
/
MVCBr.Patterns.Strategy.pas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
unit MVCBr.Patterns.Strategy;
interface
uses System.Classes, System.SysUtils;
type
IMVCBrStrategy<T:Class> = interface(TFunc<T>)
['{3FA5AD7A-D4C4-41F0-B283-7BE29E1A89E7}']
function This: TObject;
function Implements(AImplements: TGuid): IMVCBrStrategy<T>;
function AsInterface: IInterface;
property Strategy:T read Invoke;
end;
TMVCBrStrategy<T: Class> = class(TInterfacedObject, IMVCBrStrategy<T>)
private
FDelegate: TFunc<T>;
FStrategy: T;
FImplements: TGuid;
function Invoke: T;
procedure SetInvoke(const Value: T);
public
constructor Create; virtual;
class function New: IMVCBrStrategy<T>; overload;static;
class function New(AInstance: T): IMVCBrStrategy<T>; overload; static;
destructor Destroy; override;
function This: TObject;
function DelegateTo(ADelegate: TFunc<T>): IMVCBrStrategy<T>;
function Implements(AImplements: TGuid): IMVCBrStrategy<T>;
function AsInterface: IInterface;
property Strategy: T read Invoke Write SetInvoke;
end;
implementation
{ TMVCBrStrategy<T> }
function TMVCBrStrategy<T>.AsInterface: IInterface;
begin
supports(FStrategy, FImplements, result);
end;
constructor TMVCBrStrategy<T>.Create;
begin
inherited Create;
end;
function TMVCBrStrategy<T>.DelegateTo(ADelegate: TFunc<T>): IMVCBrStrategy<T>;
begin
result := self;
FDelegate := ADelegate;
end;
destructor TMVCBrStrategy<T>.Destroy;
begin
FreeAndNil(FStrategy);
inherited;
end;
function TMVCBrStrategy<T>.Invoke: T;
begin
if (not assigned(FStrategy)) and assigned(FDelegate) then
FStrategy := FDelegate();
result := FStrategy;
end;
function TMVCBrStrategy<T>.Implements(AImplements: TGuid): IMVCBrStrategy<T>;
begin
result := self;
FImplements := AImplements;
end;
class function TMVCBrStrategy<T>.New(AInstance: T): IMVCBrStrategy<T>;
var
obj: TMVCBrStrategy<T>;
begin
obj := TMVCBrStrategy<T>.Create;
obj.Strategy := AInstance;
result := obj;
end;
class function TMVCBrStrategy<T>.New: IMVCBrStrategy<T>;
var
AInstance: TMVCBrStrategy<T>;
begin
AInstance := TMVCBrStrategy<T>.Create;
result := AInstance;
end;
procedure TMVCBrStrategy<T>.SetInvoke(const Value: T);
begin
FStrategy := Value;
end;
function TMVCBrStrategy<T>.This: TObject;
begin
result := self;
end;
end.