Delphi 设计模式:《HeadFirst设计模式》Delphi7代码---状态模式[转]

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

//工程文件

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.

//运行结果

时间: 2024-10-11 16:37:44

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

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

1.概述 在软件开发过程中,应用程序可能会根据不同的情况作出不同的处理.最直接的解决方案是将这些所有可能发生的情况全都考虑到.然后使用if... ellse语句来做状态判断来进行不同情况的处理.但是对复杂状态的判断就显得“力不从心了”.随着增加新的状态或者修改一个状体(if else(或switch case)语句的增多或者修改)可能会引起很大的修改,而程序的可读性,扩展性也会变得很弱.维护也会很麻烦.那么我就考虑只修改自身状态的模式. 例子1:按钮来控制一个电梯的状态,一个电梯开们,关门,停,

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

设计模式之第21章-状态模式(Java实现) “what are you 干啥了?怎么这么萎靡不振?”“昨晚又是补新番,又是补小笼包,睡得有点晚啊.话说杨过的那个雕兄真是太好了,每天给找蛇胆,又陪练武功的,想不无敌都难啊,还有那个blablabla”(作者已被拖走).咳咳,今天那个状态哥哥马不停蹄的赶过来,下面闪亮登场. 状态模式之自我介绍 今天不在状态,可能是由于宇宙差的原因,好了,先说下定义:Allow an object to alter its behavior when its int

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

简单工厂:工厂依据传进的参数创建相应的产品. http://www.cnblogs.com/DelphiDesignPatterns/archive/2009/07/24/1530536.html {<HeadFirst设计模式>工厂模式之简单工厂 } 3{ 产品类 } 4{ 编译工具 :Delphi7.0 } 5{ 联系方式 :[email protected]com } 6 7unit uProducts; 8 9interface 10 11type 12 TPizza = class(

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

 1 2{<HeadFirst设计模式>之策略模式 } 3{ 本单元中的类为策略类           } 4{ 编译工具: Delphi7.0           } 5{ E-Mail : [email protected]   } 6 7unit uStrategy; 8 9interface1011type12  {飞行接口,及其实现类 }1314  IFlyBehavior = Interface(IInterface)15    procedure Fly;16  end;1718

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

容器的主要职责有两个:存放元素和浏览元素.根据单一职责原则(SRP)要将二者分开,于是将浏览功能打包封装就有了迭代器. 用迭代器封装对动态数组的遍历:  1 2{<HeadFirst设计模式>之迭代器模式 } 3{ 容器中的元素类                  } 4{ 编译工具:Delphi7.0             } 5{ E-Mail :[email protected]     } 6 7unit uItem; 8 9interface1011type12  TMenuIte

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

模板方法模式定义了一个算法骨架,允许子类对算法的某个或某些步骤进行重写(override).   1  2{<HeadFirst设计模式>之模板方法模式 }  3{ 编译工具: Delphi7.0              }  4{ E-Mail : [email protected]      }  5  6unit uCoffeineBeverageWithHook;  7  8interface  9 10uses 11  SysUtils; 12 13type 14  TCoffei

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

  1  2{<HeadFirst设计模式>之命令模式 }  3{ 本单元中的类为命令的接收者      }  4{ 编译工具 :Delphi7.0         }  5{ 联系方式 :[email protected] }  6  7unit uReceiveObject;  8  9interface 10 11type 12  TLight = class(TObject) 13  private 14    FLocation: String; 15  public 16    c

设计模式(十五)状态模式

相关文章 设计模式系列 前言 建议在阅读本文前先阅读设计模式(十一)策略模式这篇文章,虽说状态模式和策略模式的结构几乎是相同的,但是它们所解决的问题是不同的,读完这两篇文章你就会有了答案. 1.状态模式定义 状态模式定义 定义:当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类. 状态模式UML图 在享元模式中有如下角色: Context:环境角色,定义客户端需要的接口,并且负责具体状态的切换. State:抽象状态角色,可以是抽象类或者接口,负责对象状态定义,并封装了环境角

【设计模式学习笔记】 之 状态模式

简介: 每种事物都有不同的状态,不同的状态会有不同的表现,通过更改状态从而改变表现的设计模式称为状态模式(state pattern) 下边会通过多个例子进行讲述,会有一些代码重用的类,请注意包名! 举例1: 人有多种心情,不同的心情会有不同的表现,这里先使用分支判断写个小例子 创建一个Person类,它持有一个表示心情的字符串,通过设置这个字符串并对这个字符串进行判断来决定产生不同的行为 1 package com.mi.state.state1; 2 3 /** 4 * 人类,拥有一个状态属