unit frmMain;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
extctrls, StdCtrls;
type
TClockTimer =
class;
TForm1 =
class;
TObservable =
class;
IClockTimer =
interface;
TDigitalClock =
class;
IObserver =
interface;
IObservable =
interface;
IObserver =
interface
['
{202BAB74-E7A6-4FEC-9F93-8D3EA8B07172}']
procedure obsUpdate(
const Observable: IUnknown);
end;
IObservable =
interface
['
{31F285F0-B80B-479D-BC35-475E6ED8A148}']
procedure obsAddObserver(observer: IObserver);
procedure obsDeleteObserver(observer: IObserver);
procedure obsNotify;
end;
TForm1 =
class(TForm)
Button1: TButton;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
fClockTimer: TClockTimer;
fDigitalClock1: TDigitalClock;
public
end;
TObservable =
class(TInterfacedObject, IObservable)
private
fController: Pointer;
fObservers: TInterfaceList;
procedure obsAddObserver(Observer: IObserver);
procedure obsDeleteObserver(Observer: IObserver);
procedure obsNotify;
public
constructor Create(
const Controller: IUnknown);
end;
IClockTimer =
interface
['
{9DC95238-36BD-4595-8DE2-B56579A51FC8}']
function GetTime: TDateTime;
end;
TClockTimer =
class(TInterfacedObject, IClockTimer, IObservable)
private
fTimer: TTimer;
fInternalTime: TDateTime;
fObservable: IObservable;
function GetTime: TDateTime;
procedure Tick(Sender: TObject);
property Observable: IObservable
read fObservable
write fObservable
implements IObservable;
public
constructor Create;
destructor Destroy;
override;
end;
TDigitalClock =
class(TPanel, IObserver)
private
procedure IObserver.obsUpdate = ObserverUpdate;
procedure ObserverUpdate(
const Observable: IUnknown);
public
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
// TObservable
constructor TObservable.Create(
const Controller: IUnknown);
begin
inherited Create;
fController:= Pointer(Controller);
end;
procedure TObservable.obsAddObserver(Observer: IObserver);
begin
if not Assigned(fObservers)
then
begin
fObservers:= TInterfaceList.Create;
end;
fObservers.Add(Observer);
obsNotify;
end;
procedure TObservable.obsDeleteObserver(Observer: IObserver);
begin
if Assigned(fObservers)
then
begin
fObservers.Remove(Observer);
if fObservers.Count = 0
then
begin
fObservers.Free;
end;
end;
end;
procedure TObservable.obsNotify;
var
i: integer;
myObserver: IObserver;
myController: IUnknown;
begin
if Assigned(fObservers)
then
begin
for i:= 0
to Pred(fObservers.Count)
do
begin
myObserver:= IObserver(fObservers.Items[i]);
myController:= IUnknown(fController);
myObserver.obsUpdate(myController);
end;
end;
end;
// TClockTimer
constructor TClockTimer.Create;
begin
inherited Create;
fTimer:= TTimer.Create(
nil);
fTimer.Interval:= 1000;
fTimer.OnTimer:= Tick;
fTimer.Enabled:= true;
fObservable:= TObservable.Create(self);
end;
destructor TClockTimer.Destroy;
begin
//ShowMessage('ClockTimer now destroying!');
fTimer.Enabled:= false;
fTimer.Free;
inherited Destroy;
end;
function TClockTimer.GetTime: TDateTime;
begin
Result:= fInternalTime;
end;
procedure TClockTimer.Tick(Sender: TObject);
begin
fInternalTime:= Now;
fObservable.obsNotify;
end;
// TDigtalClock
procedure TDigitalClock.ObserverUpdate(
const Observable: IUnknown);
var
Obj: IClockTimer;
begin
Observable.QueryInterface(IClockTimer, Obj);
if Assigned(Obj)
then
begin
Caption:= FormatDateTime('
tt', Obj.GetTime);
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
fClockTimer:= TClockTimer.Create;
fDigitalClock1:= TDigitalClock.Create(self);
fDigitalClock1.Parent:= self;
fDigitalClock1.Align:= alLeft;
fDigitalClock1.Font.Size:= 14;
fDigitalClock1.Font.Style:= [fsBold];
end;
procedure TForm1.Button1Click(Sender: TObject);
var
myObservable: IObservable;
myObserver: IObserver;
begin
myObservable:= IObservable(fClockTimer);
myObserver:= IObserver(fDigitalClock1);
myObservable.obsAddObserver(myObserver );
end;
end.