zoukankan      html  css  js  c++  java
  • 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.

    //运行结果

     
     
  • 相关阅读:
    2653 区间xor
    c++位运算
    洛谷P1233 木棍加工
    c++背包问题
    FOC基本调试方法[转]
    用于下载AD官网登录账号:User name: fuxin918@fuxin918.com Passeword: s6c0W1w8
    STC10F10XE定时器中断输出10KHz的方波程序
    学习DSP(三)安装C2833x/C2823x C/C++ 头文件和外设示例-压缩包
    学DSP(二):目标芯片28335,GO!
    学DSP(一):开始
  • 原文地址:https://www.cnblogs.com/0x2D-0x22/p/4076155.html
Copyright © 2011-2022 走看看