{没有应用状态模式的代码}

//工程文件

program Project1;

{$APPTYPE CONSOLE}

uses
  uGumballMachine in 'uGumballMachine.pas';

var
  aGumballMachine: TGumballMachine;

begin
  aGumballMachine := TGumballMachine.Create(5);

aGumballMachine.InsertQuarter;
  aGumballMachine.TurnCrank;

Writeln;

aGumballMachine.InsertQuarter;
  aGumballMachine.EjectQuarter;
  aGumballMachine.TurnCrank;

Writeln;

aGumballMachine.InsertQuarter;
  aGumballMachine.TurnCrank;
  aGumballMachine.InsertQuarter;
  aGumballMachine.TurnCrank;
  aGumballMachine.EjectQuarter;

Writeln;

aGumballMachine.InsertQuarter;
  aGumballMachine.InsertQuarter;
  aGumballMachine.TurnCrank;
  aGumballMachine.InsertQuarter;
  aGumballMachine.TurnCrank;
  aGumballMachine.InsertQuarter;
  aGumballMachine.TurnCrank;

aGumballMachine.Free;

Readln;
end.

//单元文件

unit uGumballMachine;

interface

type
  TGumballMachine = class(TObject)
  private
    FState: Integer;
    FCount: Integer;
  public
    constructor Create(aCount: Integer);
    procedure InsertQuarter;
    procedure EjectQuarter;
    procedure TurnCrank;
    procedure Dispense;
  end;

implementation

const
  SOLD_OUT = 0;
  NO_QUARTER = 1;
  HAS_QUARTER = 2;
  SOLD = 3;

{ TGumballMachine }

constructor TGumballMachine.Create(aCount: Integer);
begin
  FCount := aCount;
  FState := SOLD_OUT;
  if FCount > 0 then
    FState := NO_QUARTER;
end;

procedure TGumballMachine.Dispense;
begin
  if FState = SOLD then
  begin
    Writeln('A gumball comes rolling out the slot');
    FCount := FCount - 1;
    if FCount = 0 then
      begin
        Writeln('Oops, out of Gumballs');
        FState := SOLD_OUT;
      end
    else
      FState := NO_QUARTER;
  end;

if FState = NO_QUARTER then
    Writeln('You need to pay first');

if FState = SOLD_OUT then
    Writeln('No gumball dispensed');

if FState = HAS_QUARTER then
    Writeln('No gumball dispensed');
end;

procedure TGumballMachine.EjectQuarter;
begin
  if FState = HAS_QUARTER then
  begin
    Writeln('Quarter returned');
    FState := NO_QUARTER;
  end;

if FState = NO_QUARTER then
    Writeln('You haven''t inserted a quarter');

if FState = SOLD then
    Writeln('Sorry, you already turned the crank');

if FState = SOLD_OUT then
    Writeln('You can''t eject, you haven''t inserted a quarter yet'); 
end;

procedure TGumballMachine.InsertQuarter;
begin
  if FState = HAS_QUARTER then
    Writeln('You can''t insert another quarter');

if FState = NO_QUARTER then
  begin
    FState := HAS_QUARTER;
    Writeln('You inserted a quarter');
  end;

if FState = SOLD_OUT then
    Writeln('You can''t insert a quarter, the machine is sold out');

if FState = SOLD then
    Writeln('Please Wait, we''re already giving you a gumball');   
end;

procedure TGumballMachine.TurnCrank;
begin
  if FState = SOLD then
    Writeln('Turning twice doesn''t get you another gumball');

if FState = NO_QUARTER then
    Writeln('You turned, but there''s no quarter');

if FState = SOLD_OUT then
    Writeln('You turned, but there''s no gumballs');

if FState = HAS_QUARTER then
  begin
    Writeln('You turned...');
    FState := SOLD;
    Dispense;
  end;
end;

end.

{应用状态模式的代码}

//工程文件

program Project1;

{$APPTYPE CONSOLE}

uses
  uGumballMachine in 'uGumballMachine.pas';

var
  aGumballMachine: TGumballMachine;

begin
  aGumballMachine := TGumballMachine.Create(5);

aGumballMachine.InsertQuarter;
  aGumballMachine.TurnCrank;

Writeln;

aGumballMachine.InsertQuarter;
  aGumballMachine.EjectQuarter;
  aGumballMachine.TurnCrank;

Writeln;

aGumballMachine.InsertQuarter;
  aGumballMachine.TurnCrank;
  aGumballMachine.InsertQuarter;
  aGumballMachine.TurnCrank;
  aGumballMachine.EjectQuarter;

Writeln;

aGumballMachine.InsertQuarter;
  aGumballMachine.InsertQuarter;
  aGumballMachine.TurnCrank;
  aGumballMachine.InsertQuarter;
  aGumballMachine.TurnCrank;
  aGumballMachine.InsertQuarter;
  aGumballMachine.TurnCrank;

aGumballMachine.Free;

Readln;
end.

//单元文件

unit uGumballMachine;

interface

type
  TState = class; //Forward声明,创建两个相互依赖的类。
  TGumballMachine = class(TObject)
  private
    FSoldOutState: TState;
    FNoQuarterState: TState;
    FHasQuarterState: TState;
    FSoldState: TState;
    FState: TState;
    FCount: Integer;
    function GetSoldOutState: TState;
    function GetNoQuarterState: TState;
    function GetHasQuarterState: TState;
    function GetSoldState: TState;
    function GetCount: Integer;
  public
    constructor Create(aNumberGumballs: Integer);
    destructor Destroy; override;
    procedure InsertQuarter;
    procedure EjectQuarter;
    procedure TurnCrank;
    procedure SetState(aState: TState);
    procedure ReleaseBall;
  end;

TState = class(TObject)
  public
    procedure InsertQuarter; virtual; abstract;
    procedure EjectQuarter; virtual; abstract;
    procedure TurnCrank; virtual; abstract;
    procedure Dispense; virtual; abstract;
  end;

TNoQuarterState = class(TState)
  private
    FGumballMachine: TGumballMachine;
  public
    constructor Create(aGumballMachine: TGumballMachine);
    procedure InsertQuarter; override;
    procedure EjectQuarter; override;
    procedure TurnCrank; override;
    procedure Dispense; override;
  end;

THasQuarterState = class(TState)
  private
    FGumballMachine: TGumballMachine;
  public
    constructor Create(aGumballMachine: TGumballMachine);
    procedure InsertQuarter; override;
    procedure EjectQuarter; override;
    procedure TurnCrank; override;
    procedure Dispense; override;
  end;

TSoldState = class(TState)
  private
    FGumballMachine: TGumballMachine;
  public
    constructor Create(aGumballMachine: TGumballMachine);
    procedure InsertQuarter; override;
    procedure EjectQuarter; override;
    procedure TurnCrank; override;
    procedure Dispense; override;
  end;

TSoldOutState = class(TState)
  private
    FGumballMachine: TGumballMachine;
  public
    constructor Create(aGumballMachine: TGumballMachine);
    procedure InsertQuarter; override;
    procedure EjectQuarter; override;
    procedure TurnCrank; override;
    procedure Dispense; override;
  end;

implementation

{ TNoQuarterState }

constructor TNoQuarterState.Create(aGumballMachine: TGumballMachine);
begin
  FGumballMachine := aGumballMachine;
end;

procedure TNoQuarterState.Dispense;
begin
  Writeln('You needed to pay first');
end;

procedure TNoQuarterState.EjectQuarter;
begin
  Writeln('You haven''t inserted a quarter');
end;

procedure TNoQuarterState.InsertQuarter;
begin
  Writeln('You inserted a quarter');
  FGumballMachine.SetState(FGumballMachine.GetHasQuarterState);
end;

procedure TNoQuarterState.TurnCrank;
begin
  Writeln('You turned, but there''s no quarter');
end;

{ THasQuarterState }

constructor THasQuarterState.Create(aGumballMachine: TGumballMachine);
begin
  FGumballMachine := aGumballMachine;
end;

procedure THasQuarterState.Dispense;
begin
  Writeln('No Gumball Dispensed');
end;

procedure THasQuarterState.EjectQuarter;
begin
  Writeln('Quarter Returned');
  FGumballMachine.SetState(FGumballMachine.GetNoQuarterState);
end;

procedure THasQuarterState.InsertQuarter;
begin
  Writeln('You can''t insert another quarter');
end;

procedure THasQuarterState.TurnCrank;
begin
  Writeln('You turned...');
  FGumballMachine.SetState(FGumballMachine.GetSoldState);
end;

{ TSoldState }

constructor TSoldState.Create(aGumballMachine: TGumballMachine);
begin
  FGumballMachine := aGumballMachine;
end;

procedure TSoldState.Dispense;
begin
  FGumballMachine.ReleaseBall;
  if FGumballMachine.GetCount > 0 then
    FGumballMachine.SetState(FGumballMachine.GetNoQuarterState)
  else
    begin
      Writeln('Oop , Out of gumballs');
      FGumballMachine.SetState(FGumballMachine.GetSoldOutState);
    end;
end;

procedure TSoldState.EjectQuarter;
begin
  Writeln('Sorry, you already turned the crank');
end;

procedure TSoldState.InsertQuarter;
begin
  Writeln('Please Wait, we''re already giving you a gumball ');
end;

procedure TSoldState.TurnCrank;
begin
  Writeln('Turning twice doesn''t get you another gumball');
end;

{ TSoldOutState }

constructor TSoldOutState.Create(aGumballMachine: TGumballMachine);
begin
  FGumballMachine := aGumballMachine;
end;

procedure TSoldOutState.Dispense;
begin
  Writeln('No gumball dispensed');
end;

procedure TSoldOutState.EjectQuarter;
begin
  Writeln('You can''t eject, you haven''t inserted a quarter yet');
end;

procedure TSoldOutState.InsertQuarter;
begin
  Writeln('You can''t insert a quarter, the machine is Sold out');
end;

procedure TSoldOutState.TurnCrank;
begin
  Writeln('You turned, but there are no gumballs');
end;

{ TGumballMachine }

constructor TGumballMachine.Create(aNumberGumballs: Integer);
begin
  FSoldOutState    := TSoldOutState.Create(Self); //var Self: TGumballMachine;
  FNoQuarterState  := TNoQuarterState.Create(Self);
  FHasQuarterState := THasQuarterState.Create(Self);
  FSoldState       := TSoldState.Create(Self);
  FCount := aNumberGumballs;
  FState := FSoldOutState;
  if aNumberGumballs > 0 then
    FState := FNoQuarterState;
end;

destructor TGumballMachine.Destroy;
begin
  FSoldOutState.Free;
  FNoQuarterState.Free;
  FHasQuarterState.Free;
  FSoldState.Free;
  inherited;
end;

procedure TGumballMachine.EjectQuarter;
begin
  FState.EjectQuarter;
end;

function TGumballMachine.GetCount: Integer;
begin
  Result := FCount;
end;

function TGumballMachine.GetHasQuarterState: TState;
begin
  Result := FHasQuarterState;
end;

function TGumballMachine.GetNoQuarterState: TState;
begin
  Result := FNoQuarterState;
end;

function TGumballMachine.GetSoldOutState: TState;
begin
  Result := FSoldOutState;
end;

function TGumballMachine.GetSoldState: TState;
begin
  Result := FSoldState;
end;

procedure TGumballMachine.InsertQuarter;
begin
  FState.InsertQuarter;
end;

procedure TGumballMachine.ReleaseBall;
begin
  Writeln('A Gumball comes rolling out the slot...');
  if FCount <> 0 then
    FCount := FCount - 1;
end;

procedure TGumballMachine.SetState(aState: TState);
begin
  FState := aState;
end;

procedure TGumballMachine.TurnCrank;
begin
  FState.TurnCrank;
  FState.Dispense;
end;

end.

//运行结果

 
 

Delphi 设计模式:《HeadFirst设计模式》Delphi7代码---状态模式[转]的更多相关文章

  1. 设计模式 ( 十八 ):State状态模式 -- 行为型

    1.概述 在软件开发过程中,应用程序可能会根据不同的情况作出不同的处理.最直接的解决方案是将这些所有可能发生的情况全都考虑到.然后使用if... ellse语句来做状态判断来进行不同情况的处理.但是对 ...

  2. 设计模式之第21章-状态模式(Java实现)

    设计模式之第21章-状态模式(Java实现) “what are you 干啥了?怎么这么萎靡不振?”“昨晚又是补新番,又是补小笼包,睡得有点晚啊.话说杨过的那个雕兄真是太好了,每天给找蛇胆,又陪练武 ...

  3. Delphi 设计模式:《HeadFirst设计模式》Delphi7代码---工厂模式之简单工厂

    简单工厂:工厂依据传进的参数创建相应的产品. http://www.cnblogs.com/DelphiDesignPatterns/archive/2009/07/24/1530536.html { ...

  4. Delphi 设计模式:《HeadFirst设计模式》Delphi7代码---模板方法模式之CoffeineBeverageWithHook[转]

    模板方法模式定义了一个算法骨架,允许子类对算法的某个或某些步骤进行重写(override).   1   2{<HeadFirst设计模式>之模板方法模式 }   3{ 编译工具: Del ...

  5. Delphi 设计模式:《HeadFirst设计模式》Delphi7代码---迭代器模式之DinerMenu[转]

    容器的主要职责有两个:存放元素和浏览元素.根据单一职责原则(SRP)要将二者分开,于是将浏览功能打包封装就有了迭代器. 用迭代器封装对动态数组的遍历:  1  2{<HeadFirst设计模式& ...

  6. Delphi 设计模式:《HeadFirst设计模式》Delphi7代码---策略模式之MiniDuckSimulator[转]

     1  2{<HeadFirst设计模式>之策略模式 }  3{ 本单元中的类为策略类           }  4{ 编译工具: Delphi7.0           }  5{ E- ...

  7. Delphi 设计模式:《HeadFirst设计模式》Delphi7代码---命令模式之RemoteControlTest[转]

      1   2{<HeadFirst设计模式>之命令模式 }   3{ 本单元中的类为命令的接收者      }   4{ 编译工具 :Delphi7.0         }   5{ 联 ...

  8. 我所理解的设计模式(C++实现)——状态模式(State Pattern)

    概述: 看看我们平时用的开关,同样一个开关他有2种状态:开和关,当她处于不同的状态的时候她的行为是不一样的,比如当她是开着的时候,你按她一下,她就变成了关闭状态,她是关着的时候按她一下,她就变成了开着 ...

  9. Javascript设计模式理论与实战:状态模式

    在软件开发中,很大部分时候就是操作数据,而不同数据下展示的结果我们将其抽象出来称为状态,我们平时开发时本质上就是对应用程序的各种状态进行切换并作出相应处理.状态模式就是一种适合多种状态场景下的设计模式 ...

随机推荐

  1. 【默默努力】h5-game-heroVSmonster

    先放下作者大大的项目地址:https://github.com/yangyunhe369/h5-game-heroVSmonster 然后游戏的效果为 截动图的按键与游戏按键应该冲突,我就截几张图片了 ...

  2. 实现Linux下不间断聊天和退出处理

    实现Linux下不间断聊天和退出处理

  3. 即将开源 | 2亿用户背后的Flutter应用框架Fish Redux

    背景 在闲鱼深度使用 Flutter 开发过程中,我们遇到了业务代码耦合严重,代码可维护性糟糕,如入泥泞.对于闲鱼这样的负责业务场景,我们需要一个统一的应用框架来摆脱当下的开发困境,而这也是 Flut ...

  4. 2-sat——输出方案poj3683

    一篇讲的详细的博客 https://blog.csdn.net/Hawo11/article/details/74908233 缩点后为什么要建立反图? 如果是按原图处理,选择一个点之后要把所有其后续 ...

  5. phpstorm中完成一键快速注释函数头

    先保存函数,再在函数头写/**+enter就行了 /** * @param $num1 * @param $num2 * @param $opt * @return float|int */ func ...

  6. 为什么说 Python 是数据科学的发动机(一)发展历程(附视频中字)

    为什么说 Python 是数据科学的发动机(一)发展历程(附视频中字) 在PyData Seattle 2017中,Jake Vanderplas介绍了Python的发展历程以及最新动态.在这里我们把 ...

  7. Docker在线文档收集

    极客学院 kubernetes中文社区 易百教程

  8. MessageBox用法

    一 函数原型及参数 function MessageBox(hWnd: HWND; Text, Caption: PChar; Type: Word): Integer; hWnd:对话框父窗口句柄, ...

  9. Ubuntu时间管理方法

    1. date 命令主要用于显示以及修改系统时间 2. hwclock 命令用于查看设置硬件时间,以及同步硬件时间与系统时间 # 显示硬件时间hwclock # 设置硬件时间hwclock -set ...

  10. Git - fatal error : Agent admitted failure to sign using the key

    提交时出现如下问题: git push -u origin master Agent admitted failure to sign using the key. Permission denied ...