State pattern (Delphi)

来源:互联网 发布:淘宝刷钻是真的吗 编辑:程序博客网 时间:2024/05/16 04:45
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.
 
原创粉丝点击