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

//工程文件

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. css,js文件后面加一个版本号

    由于前几天,更新了项目,更新的文件有js文件,今天客人截图过来,我发现修改之后的效果没有显示出来,我回复说清理浏览器缓存.到了晚上,客人找老板,说还没有处理到這个,说客人不懂這个.所以想到之前自己为了 ...

  2. [转]async & await 的前世今生(Updated)

    async 和 await 出现在C# 5.0之后,给并行编程带来了不少的方便,特别是当在MVC中的Action也变成async之后,有点开始什么都是async的味道了.但是这也给我们编程埋下了一些隐 ...

  3. [JZOJ3293] 【SHTSC2013】阶乘字符串

    题目 题目大意 给你一个字符串,判断这个字符串是否为"阶乘字符串". 就是子序列包含字符集的全排列的字符串. n≤26n\leq 26n≤26 ∣S∣≤450|S|\leq 450 ...

  4. 集合遍历remove时ConcurrentModificationException异常

    1.集合遍历时候,有时候需要remove或add操作,这时候遍历方式可能会影响程序运行 例如: @Test public void test1() { List<Integer> intL ...

  5. js摇一摇事件

    今早同事过来说.要做个小游戏.里面有个摇一摇动作. 平时都是做的手机营销h5比较少.  发现很有意思.  一时间没有反应过来. 怎么实现的摇一摇. 现在吧代码叠出来给2货的我. //运动事件监听if ...

  6. vmware centos 扩容

    1.停止后vmware 扩容 2.centos 增加分区 #增加分区fdisk /dev/sda 操作 /dev/sda 的分区表 p 查看已分区数量(我看到有两个 /dev/sda1 /dev/sd ...

  7. java面向对象特征 — 一句话概括

    java基础学习总结之基本特征,最开始学习的时候,是形而上的理解,用了3年多,再回头看,理解起来颇为顺理成章 语言学习大概就是这样一种规律,学习,不甚解,应用,应用,渐深入人心,回头一看,恍然一悟 最 ...

  8. eclipse memory analyzer对系统内存溢出堆文件解析(转)

    本文转之:https://blog.csdn.net/rachel_luo/article/details/8992461 前言 性能分析工具之-- Eclipse Memory Analyzer t ...

  9. 13_数据的划分和介绍之sklearn数据集

    1.数据集是如何划分?训练数据和评估数据不能使用相同数据,不然自己测自己,会使得准确率虚高,在遇到陌生数据时,不够准确. 2.数据集的获取: 通过load或者fetch方法. 3.数据集进行分割: 训 ...

  10. 使用RequestsCookieJar自动保存并传递cookie

    使用python的requests开发爬虫程序的时候,经常需要将之前请求返回的cookie值作为下一个请求的cookie进行调用,比如模拟登录之后的返回的sessionID,就是需要作为后续请求的co ...