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

//工程文件

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. 廖雪峰Java15JDBC编程-2SQL入门-2insert/select/update/delete

    1. INSERT用于向数据库的表中插入1条记录 insert into 表名 (字段1,字段2,...) values (数据1,数据2,数据3...) 示例 -- 如果表存在,就删除 drop t ...

  2. MySQL其他和备份

    目录 事务 存储引擎 InnoDB存储引擎 数据存储形式 锁的粒度 事务 数据的存储特点 MyISAM存储引擎 数据存储形式 锁的粒度 事务 数据的存储特点 其他 对比与选择 视图 触发器 存储过程 ...

  3. iOS之CATiledLayer的属性简介和使用

    1.CATiledLayer简介 CATiledLayer用于大型图片进行分割显示,需要显示的图片才会加载,直接上代码: - (void)viewDidLoad { [super viewDidLoa ...

  4. JPA 中注解的作用

    JPA全称Java Persistence API.JPA通过JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中.        JPA由EJB 3.0软件专家 ...

  5. php构造方法(函数)基础

    什么是构造函数呢?在回答这个问题之前,我们来看一个需求:我们在创建人类的对象时,是先把一个对象创建好后,再给他的年龄和姓名属性赋值,如果现在我要求,在创建人类的对象时,就指定这个对象的年龄和姓名,该怎 ...

  6. python学习笔记3.2_数据导出

    一.data.to_csv:数据导出 1.to_csv:将数据导出为逗号分隔的文件 2.输出为其他分隔符的文件 写入到控制台,并打印:sys.stdout na_rep:对空值进行标注 二.serie ...

  7. C# 把十六进制表示的ASCII码转换为对应的字符组成的字符串

    0x30表示字符‘0’的ASCII码.

  8. nfs 原理详解

    一.NFS介绍 1)什么是NFS 它的主要功能是通过网络让不同的机器系统之间可以彼此共享文件和目录.NFS服务器可以允许NFS客户端将远端NFS服务器端的共享目录挂载到本地的NFS客户端中.在本地的N ...

  9. [欧拉路]CF1152E Neko and Flashback

    1152E - Neko and Flashback 题意:对于长为n的序列c和长为n - 1的排列p,我们可以按照如下方法得到长为n - 1的序列a,b,a',b'. ai = min(ci, ci ...

  10. JS对象和数组深浅拷贝总结②

    在实际开发中遇到过太多次深拷贝浅拷贝的问题.总结一下~ JS数据存储和深浅拷贝实际运用① 这是之前写过的一篇文章,解决浅拷贝深拷贝的问题只说了一种方法,今天来补充一下. 介绍深拷贝和浅拷贝都在上一篇文 ...