打印本文 打印本文 关闭窗口 关闭窗口
Delphi模式编程之策略模式(下)
作者:武汉SEO闵涛  文章来源:敏韬网  点击数1098  更新时间:2009/4/23 18:35:03  文章录入:mintao  责任编辑:mintao

Delphi模式编程之策略模式(续)

 

刘 艺

1.3                         策略模式在酒店管理系统中的应用

在酒店管理系统中,通常客房的价格不是一成不变的。对于住宿的淡季和旺季、老客户和新客户、散客和团队,都应该有不同的销售策略。显然,销售策略决定了报价。但是基于销售策略的报价体系又不能绑定于某一具体的客户端,因为只有把基于销售策略的报价体系独立出来,才能保证其重用性和可维护性。比如:一种报价体系一方面满足了优惠房价查询、客房结算等多个客户端的使用,另一方面又满足了不断调整的新销售策略的需求,这才算真正做到了重用性和可维护性。

对于以上的设计要求,选用策略模式是最好不过了。策略模式能够让算法变化独立于使用它的客户端。范例程序是一个基于策略模式的优惠房价查询模块,它包括一个基于销售策略的报价体系和一个优惠房价查询界面。当然,优惠房价查询界面只是该报价体系的客户端之一,报价体系亦可被其他客户端使用。

优惠房价查询模块的设计如图 1‑6所示。它包括了:

·           销售策略类TSaleStrategy,它是具体销售策略类的抽象基类。

·           3个具体销售策略类:TVIPStrategy (VIP卡销售策略)、TTeamStrategy (团队销售策略)、TSeasonStrategy(季节销售策略)。

·           报价类TPriceContext,它是该策略模式中的上下文,持有一个到TStrategy的引用。

·           客户端类TClient,它是一个窗体类,即房价查询的界面。

 

图 1‑6 基于策略模式的优惠房价查询模块

示例程序 1‑1是HotelSaleStrategy单元的源代码,该单元包含了基于销售策略的报价体系的业务逻辑,用策略模式实现。TSaleStrategy作为销售策略的抽象基类,其目的是提供一个通用的接口。虚抽象函数SalePrice就是这样一个接口。由于3个具体销售策略分别是根据季节、VIP卡、团队人数来制定销售策略的,所以基类接口SalePrice的参数设计必须满足3个派生类的不同需求。TSaleStrategy的SalePrice函数声明如下:

 

function SalePrice(price:Currency;value:integer):Currency;

virtual; abstract;

 

 

它的第一个参数表示传入的固定房价,第二个参数表示传入的优惠条件,该条件因不同的派生类而异。在季节销售策略TSeasonStrategy中,该参数表示为入住月份;在VIP卡销售策略TVIPStrategy中,该参数表示为VIP卡的种类;在团队销售策略TTeamStrategy中,该参数表示为团队人数。我们发现,这些参数都可以用整数类型,所以在基类中,巧妙地用一个value参数解决了派生类的不同参数需求。这样一来,可以直接让TPriceContext将数据放在参数中传递给不同的销售策略类操作,避免了参数冗余。

 

{TPriceContext }

function TPriceContext.GetPrice(price:Currency;value:integer):Currency;

begin

  result:=Strategy.SalePrice(price,value);

end;

 

TPriceContext在该策略模式中起着上下文作用,它负责引用销售策略对象的不同实例,调用SalePrice接口,动态配置具体的折扣算法,并返回实际销售价格。由于有了TPriceContext的中介,客户端无需知道具体销售策略是如何实现的;同样,当销售策略进行更新调整时,对客户端程序亦无影响。

示例程序 1‑1 HotelSaleStrategy单元的源代码

unit HotelSaleStrategy;

 

interface

 

uses

  SysUtils, Windows, Messages, Classes, Graphics, Controls,

  Forms, Dialogs;

 

type

  TSaleStrategy = class (TObject)

  public

    function SalePrice(price:Currency;value:integer):Currency;

virtual; abstract;

  end;

 

  TSeasonStrategy = class (TSaleStrategy)

  public

    function SalePrice(price:Currency;value:integer):Currency; override;

  end;

 

  TVIPStrategy = class (TSaleStrategy)

  public

    function SalePrice(price:Currency;value:integer):Currency; override;

  end;

 

  TTeamStrategy = class (TSaleStrategy)

  public

    function SalePrice(price:Currency;value:integer):Currency; override;

  end;

 

  TPriceContext = class (TObject)

  private

    FStrategy: TSaleStrategy;

    procedure SetStrategy(Value: TSaleStrategy);

  public

    function GetPrice(price:Currency;value:integer):Currency;

    property Strategy: TSaleStrategy read FStrategy write SetStrategy;

  end;

 

implementation

 

{TSeasonStrategy }

function TSeasonStrategy.SalePrice(price:Currency;value:integer):Currency;

begin

  //季节销售策略

  {

  2、3、11月8.5折优惠,

  4、6月9折优惠。

  8、9月9.5折优惠。

  }

  case value of

    2,3,11:result:=price*0.85;

    4,6:result:=price*0.9;

    8,9:result:=price*0.95;

    else

      result:=price;

  end;

end;

 

{TVIPStrategy }

function TVIPStrategy.SalePrice(price:Currency;value:integer):Currency;

begin

  //VIP卡销售策略

  {

  0:VIP银卡 9折优惠

  1:VIP金卡 8折优惠

  2:VIP钻石卡 7 折优惠

  }

 

  case value of

    0:result:=price*0.9;

    1:result:=price*0.8;

    2:result:=price*0.7;

  end;

end;

 

{TTeamStrategy }

function TTeamStrategy.SalePrice(price:Currency;value:integer):Currency;

begin

  //团队销售策略

  {

  3-5人团队9折优惠;

  6-10人团队8折优惠;

  11-20人团队7折优惠;

  20人以上团队6折优惠。

  }

  result:=price;

  if (value<6) and (value>2) then  result:=price*0.9;

  if (value<11) and (value>5) then  result:=price*0.8;

  if (value<21) and (value>10) then  result:=price*0.7;

  if (value>20) then  result:=price*0.6;

end;

 

{TPriceContext }

function TPriceContext.GetPrice(price:Currency;value:integer):Currency;

begin

  result:=Strategy.SalePrice(price,value);

end;

 

procedure TPriceContext.SetStrategy(Value: TSaleStrategy);

begin

  FStrategy:=Value;

end;

 

end.

 

优惠房价查询模块的客户端程序如示例程序 1‑2所示。该程序提供一个用户选择界面,使得查询者可以任选一种优惠方案。一旦选定优惠条件和公开房价,点击“查询优惠房价”按钮,便得到打折后的优惠价。实际运行效果如图 1‑7所示。

示例程序 1‑2 ClientForm单元的源代码

unit ClientForm;

 

interface

 

uses

  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

  Dialogs, StdCtrls, ExtCtrls,HotelSaleStrategy, ComCtrls,DateUtils;

 

type

  TClient = class(TForm)

    RadioGroup1: TRadioGroup;

    btnCheck: TButton;

    btnExit: TButton;

    dtpDate: TDateTimePicker;

    cmbVIP: TComboBox;

    Label1: TLabel;

    Label2: TLabel;

    cmbPrice: TComboBox;

    edtPrice: TEdit;

    Label3: TLabel;

    edtCount: TEdit;

    Label4: TLabel;

    Label5: TLabel;

    Bevel1: TBevel;

    procedure FormCreate(Sender: TObject);

    procedure btnCheckClick(Sender: TObject);

    procedure FormDestroy(Sender: TObject);

    procedure btnExitClick(S

[1] [2]  下一页

打印本文 打印本文 关闭窗口 关闭窗口