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

//工程文件

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. linux yum 安装 卸载

    安装一个软件时 yum -y install httpd 安装多个相类似的软件时 yum -y install httpd* 安装多个非类似软件时 yum -y install httpd php p ...

  2. 边缘节点服务ENS重磅升级 阿里云首次定义“边缘云计算”概念层层深入

    随着5G.物联网时代的到来以及云计算应用的逐渐增加,传统集中式的云计算技术已经无法满足终端侧“大连接,低时延,大带宽”的需求.结合边缘计算的概念,云计算将必然发展到下一个技术阶段,也就是将云计算的能力 ...

  3. nc 文件的nan识别

    表现形式:print()结果为 --      打印type为numpy.ma.core.MaskedConstant 使用 if type(x) == np.ma.core.MaskedConsta ...

  4. SQLServer中使用索引视图

    在SQL Server中,视图是一个保存的T-SQL查询.视图定义由SQL Server保存,以便它能够用作一个虚拟表来简化查询,并给基表增加另一层安全.但是,它并不占用数据库的任何空间.实际上,在你 ...

  5. iOS之String动态书写

    /** String动画书写出来 @param string 要写的字 @param view 父视图 @param ui_font 字体大小 @param color 字体颜色 */ - (void ...

  6. Logback 日志组件的使用

    Logback 是由 log4j 创始人设计的又一个开源日志组件. 一. logback 的介绍 ​ logback 当前分成三个模块:logback-core,logback- classic 和 ...

  7. Spring Cloud Alibaba 使用Sentinel实现接口限流

    Sentinel是什么 Sentinel的官方标题是:分布式系统的流量防卫兵.从名字上来看,很容易就能猜到它是用来作服务稳定性保障的.对于服务稳定性保障组件,如果熟悉Spring Cloud的用户,第 ...

  8. Java 多线程同步和异步详解

    java线程 同步与异步 线程池 1)多线程并发时,多个线程同时请求同一个资源,必然导致此资源的数据不安全,A线程修改了B线 程的处理的数据,而B线程又修改了A线程处理的数理.显然这是由于全局资源造成 ...

  9. 阿里云安全研究成果入选人工智能顶级会议 IJCAI 2019, 业界首次用AI解决又一难题!

    8月10日至8月16日,国际人工智能组织联合会议IJCAI 2019(International Joint Conference on Artificial Intelligence 2019)在中 ...

  10. CSP-S模拟41影子,玫瑰花精题解

    题面:https://www.cnblogs.com/Juve/articles/11523567.html 影子: 暴力方法:枚举每一对点暴力统计最小权 优化:考虑并查集,枚举每个点,如果没有被访问 ...