unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TState = class;
TEmptyState = class;
TSurplusState = class;
TOverdrawState = class;
TAccount = class
private
amount: double;
state: TState;
EmptyState: TState;
SurplusState: TState;
OverdrawState: TState;
public
constructor Create;
destructor Destroy;
procedure deposit(amt: double);
procedure withdraw(amt: double);
end;
TState = class
protected
account: TAccount;
public
constructor Create(Acct: TAccount);
destructor Destroy;
function GetName: string; virtual;
procedure deposit(amt: double);
procedure withdraw(amt: double);
procedure report(msg: string; amt: double);
procedure update_state;
end;
TEmptyState = class(TState)
public
function GetName: string; override;
end;
TSurplusState = class(TState)
public
function GetName: string; override;
end;
TOverdrawState = class(TState)
public
function GetName: string; override;
end;
TForm1 = class(TForm)
Button1: TButton;
ListBox1: TListBox;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
{ TAccount }
constructor TAccount.Create;
begin
EmptyState := TEmptyState.Create(Self);
SurplusState := TSurplusState.Create(Self);
OverdrawState := TOverdrawState.Create(Self);
state := EmptyState;
amount := 0;
end;
procedure TAccount.deposit(amt: double);
begin
state.deposit(amt);
end;
destructor TAccount.Destroy;
begin
EmptyState.Destroy;
SurplusState.Destroy;
OverdrawState.Destroy;
// FreeAndNil(EmptyState);
// FreeAndNil(SurplusState);
// FreeAndNil(OverdrawState);
end;
procedure TAccount.withdraw(amt: double);
begin
state.withdraw(amt);
end;
{ TState }
constructor TState.Create(Acct: TAccount);
begin
account := Acct;
end;
procedure TState.deposit(amt: double);
begin
account.amount := account.amount + amt;
update_state;
report('deposit', amt);
end;
destructor TState.Destroy;
begin
end;
function TState.GetName: string;
begin
Result := 'State';
end;
procedure TState.report(msg: string; amt: double);
begin
Form1.ListBox1.Items.Add('');
Form1.ListBox1.Items.Add('-- TRANSACTION MEMO --');
Form1.ListBox1.Items.Add(msg + ' ' + FloatToStr(amt));
Form1.ListBox1.Items.Add('Balanced Amount = ' + FloatToStr(account.amount));
Form1.ListBox1.Items.Add('STATE: ' + account.state.GetName());
end;
procedure TState.update_state;
begin
if account.amount < 0 then
account.state := account.OverdrawState
else if account.amount = 0 then
account.state := account.EmptyState
else
account.state := account.SurplusState;
end;
procedure TState.withdraw(amt: double);
begin
account.amount := account.amount - amt;
update_state;
report('withdraw', amt);
end;
///
procedure TForm1.Button1Click(Sender: TObject);
var AC: TAccount;
begin
AC := TAccount.Create;
AC.withdraw(100);
AC.deposit(300);
AC.Destroy;
end;
{ TEmptyState }
function TEmptyState.GetName: string;
begin
Result := 'EmptyState';
end;
{ TOverdrawState }
function TOverdrawState.GetName: string;
begin
Result := 'OverdrawState';
end;
{ TSurplusState }
function TSurplusState.GetName: string;
begin
Result := 'SurplusState';
end;
end.
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TState = class;
TEmptyState = class;
TSurplusState = class;
TOverdrawState = class;
TAccount = class
private
amount: double;
state: TState;
EmptyState: TState;
SurplusState: TState;
OverdrawState: TState;
public
constructor Create;
destructor Destroy;
procedure deposit(amt: double);
procedure withdraw(amt: double);
end;
TState = class
protected
account: TAccount;
public
constructor Create(Acct: TAccount);
destructor Destroy;
function GetName: string; virtual;
procedure deposit(amt: double);
procedure withdraw(amt: double);
procedure report(msg: string; amt: double);
procedure update_state;
end;
TEmptyState = class(TState)
public
function GetName: string; override;
end;
TSurplusState = class(TState)
public
function GetName: string; override;
end;
TOverdrawState = class(TState)
public
function GetName: string; override;
end;
TForm1 = class(TForm)
Button1: TButton;
ListBox1: TListBox;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
{ TAccount }
constructor TAccount.Create;
begin
EmptyState := TEmptyState.Create(Self);
SurplusState := TSurplusState.Create(Self);
OverdrawState := TOverdrawState.Create(Self);
state := EmptyState;
amount := 0;
end;
procedure TAccount.deposit(amt: double);
begin
state.deposit(amt);
end;
destructor TAccount.Destroy;
begin
EmptyState.Destroy;
SurplusState.Destroy;
OverdrawState.Destroy;
// FreeAndNil(EmptyState);
// FreeAndNil(SurplusState);
// FreeAndNil(OverdrawState);
end;
procedure TAccount.withdraw(amt: double);
begin
state.withdraw(amt);
end;
{ TState }
constructor TState.Create(Acct: TAccount);
begin
account := Acct;
end;
procedure TState.deposit(amt: double);
begin
account.amount := account.amount + amt;
update_state;
report('deposit', amt);
end;
destructor TState.Destroy;
begin
end;
function TState.GetName: string;
begin
Result := 'State';
end;
procedure TState.report(msg: string; amt: double);
begin
Form1.ListBox1.Items.Add('');
Form1.ListBox1.Items.Add('-- TRANSACTION MEMO --');
Form1.ListBox1.Items.Add(msg + ' ' + FloatToStr(amt));
Form1.ListBox1.Items.Add('Balanced Amount = ' + FloatToStr(account.amount));
Form1.ListBox1.Items.Add('STATE: ' + account.state.GetName());
end;
procedure TState.update_state;
begin
if account.amount < 0 then
account.state := account.OverdrawState
else if account.amount = 0 then
account.state := account.EmptyState
else
account.state := account.SurplusState;
end;
procedure TState.withdraw(amt: double);
begin
account.amount := account.amount - amt;
update_state;
report('withdraw', amt);
end;
///
procedure TForm1.Button1Click(Sender: TObject);
var AC: TAccount;
begin
AC := TAccount.Create;
AC.withdraw(100);
AC.deposit(300);
AC.Destroy;
end;
{ TEmptyState }
function TEmptyState.GetName: string;
begin
Result := 'EmptyState';
end;
{ TOverdrawState }
function TOverdrawState.GetName: string;
begin
Result := 'OverdrawState';
end;
{ TSurplusState }
function TSurplusState.GetName: string;
begin
Result := 'SurplusState';
end;
end.