-
Notifications
You must be signed in to change notification settings - Fork 77
/
Behavioral.Observer.Pattern.pas
123 lines (102 loc) · 2.38 KB
/
Behavioral.Observer.Pattern.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
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
unit Behavioral.Observer.Pattern;
interface
uses Classes, SysUtils;
type
IObserver = interface
['{A3208B98-3F48-40C6-9986-43B6CB8F4A7E}']
procedure Update(Subject: TObject);
end;
ISubject = interface
['{CA063853-73A8-4AFE-8CAA-50600996ADEB}']
procedure Attach(Observer: IObserver);
procedure Detach(Observer: IObserver);
procedure Notify;
end;
TStock = class(TInterfacedObject, ISubject)
private
FSymbol: string;
FPrice: Double;
FInvestors: TInterfaceList;
function ReadSymbol: string;
function ReadPrice: Double;
procedure SetPrice(value: Double);
public
constructor Create(symbol: string; price: Double);
destructor Destroy; override;
procedure Attach(Observer: IObserver);
procedure Detach(Observer: IObserver);
procedure Notify;
property Symbol: string read ReadSymbol;
property Price: Double read ReadPrice write SetPrice;
end;
TInvestor = class(TINterfacedObject, IObserver)
private
FName: string;
public
constructor Create(name: string);
procedure Update(Subject: TObject);
end;
implementation
{ TStock }
procedure TStock.Attach(Observer: IObserver);
begin
if FInvestors = nil then
FInvestors := TInterfaceList.Create;
if FInvestors.IndexOf(Observer) < 0 then
FInvestors.Add(Observer);
end;
constructor TStock.Create(symbol: string; price: Double);
begin
FSymbol := symbol;
FPrice := price;
end;
destructor TStock.Destroy;
begin
FInvestors.Free;
inherited;
end;
procedure TStock.Detach(Observer: IObserver);
begin
if FInvestors <> nil then
begin
FInvestors.Remove(Observer);
if FInvestors.Count = 0 then
begin
FInvestors.Free;
FInvestors := nil;
end;
end;
end;
procedure TStock.Notify;
var
i: Integer;
begin
if FInvestors <> nil then
for i := 0 to Pred(FInvestors.Count) do
IObserver(FInvestors[i]).Update(Self);
end;
function TStock.ReadPrice: Double;
begin
Result := FPrice;
end;
function TStock.ReadSymbol: string;
begin
Result := FSymbol
end;
procedure TStock.SetPrice(value: Double);
begin
if value <> FPrice then begin
FPrice := value;
Notify;
end;
end;
{ TInvestor }
constructor TInvestor.Create(name: string);
begin
FName := name;
end;
procedure TInvestor.Update(Subject: TObject);
begin
WriteLn(Format('Notified %s of %s change to %g', [FName, TStock(Subject).Symbol, TStock(Subject).Price]));
end;
end.