亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > Delphi > 正文

Delphi模式編程之策略模式(下)

2019-11-18 18:23:03
字體:
來源:轉載
供稿:網友

Delphi模式編程之策略模式(續)

劉 藝

1.3                         策略模式在酒店管理系統中的應用

在酒店管理系統中,通??头康膬r格不是一成不變的。對于住宿的淡季和旺季、老客戶和新客戶、散客和團隊,都應該有不同的銷售策略。顯然,銷售策略決定了報價。但是基于銷售策略的報價體系又不能綁定于某一具體的客戶端,因為只有把基于銷售策略的報價體系獨立出來,才能保證其重用性和可維護性。比如:一種報價體系一方面滿足了優惠房價查詢、客房結算等多個客戶端的使用,另一方面又滿足了不斷調整的新銷售策略的需求,這才算真正做到了重用性和可維護性。
對于以上的設計要求,選用策略模式是最好不過了。策略模式能夠讓算法變化獨立于使用它的客戶端。范例程序是一個基于策略模式的優惠房價查詢模塊,它包括一個基于銷售策略的報價體系和一個優惠房價查詢界面。當然,優惠房價查詢界面只是該報價體系的客戶端之一,報價體系亦可被其他客戶端使用。
優惠房價查詢模塊的設計如圖 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(Sender: TObject);
    procedure RadioGroup1Click(Sender: TObject);
  private
    FSeasonStrategy:TSaleStrategy;
    FVIPStrategy:TSaleStrategy;
    FTeamStrategy:TSaleStrategy;
    FPriceSys:TPriceContext;
  public
    { Public declarations }
  end;
 
var
  Client: TClient;
 
implementation
 
 
{$R *.dfm}
 
procedure TClient.FormCreate(Sender: TObject);
begin
  FSeasonStrategy:=TSeasonStrategy.Create;
  FVIPStrategy:=TVIPStrategy.Create;
  FTeamStrategy:=TTeamStrategy.Create;
  FPriceSys:=TPriceContext.Create;
end;
 
procedure TClient.btnCheckClick(Sender: TObject);
var
  i:integer;
  price:Currency;
begin
  case RadioGroup1.ItemIndex of
    0:begin
        FPriceSys.Strategy:=FSeasonStrategy ;
        i:=MonthOf(dtpDate.DateTime);
      end;
    1:begin
        FPriceSys.Strategy:=FVIPStrategy ;
        i:=cmbVIP.ItemIndex;
      end;
    2:begin
        FPriceSys.Strategy:=FTeamStrategy  ;
        i:=StrToInt(edtCount.Text);
      end;
  end;
  case cmbPrice.ItemIndex of
    0:price:=300 ; //甲類標準間300元
    1:price:=500 ; //乙類標準間500元
    2:price:=800 ; //貴賓間800元
    3:price:=1000; //商務套房1000元
    4:price:=2000; // 豪華套房2000元
  end;
  edtPrice.Text:=CurrToStr(FPriceSys.GetPrice(price,i));
end;
 
procedure TClient.FormDestroy(Sender: TObject);
begin
  FPriceSys.Free;
  FSeasonStrategy.Free;
  FVIPStrategy.Free;
  FTeamStrategy.Free;
end;
 
procedure TClient.btnExitClick(Sender: TObject);
begin
  close;
end;
 
procedure TClient.RadioGroup1Click(Sender: TObject);
begin
  dtpDate.Enabled:=false;
  edtCount.Enabled:=false;
  cmbVIP.Enabled:=false;
  case RadioGroup1.ItemIndex of
    0:dtpDate.Enabled:=true;
    1:cmbVIP.Enabled:=true;
    2:edtCount.Enabled:=true;
  end;
end;
 
end.
1‑7優惠房價查詢模塊的實際運行界面

1.4                         實踐小結

通過前面范例的演示和剖析,我們進一步討論策略模式如下:
·           策略模式提供了管理算法集的辦法。策略類的層次結構為TContext定義了一系列的可供重用的算法或行為。TStrategy基類析取出這些算法中的公共功能,派生類通過繼承豐富了算法的差異和種類,又避免了重復的代碼。
·           如果不將算法和使用算法的上下文分開,直接生成一個包含算法的TContext類的派生類,給它以不同的行為,這將會把行為寫死到TContext中,而將算法的實現與TContext的實現混合起來,從而使TContext難以理解、難以維護和難以擴展。最后得到一大堆相關的類, 它們之間的唯一差別是它們所使用的算法。顯然,類的繼承關系是強關聯,繼承關系無法動態地改變算法;而對象的合成關系是弱關聯,通過組合策略類對象,使得算法可以獨立于使用算法的環境(TContext)而獨立演化。
·           使用策略模式可以對大量使用條件分支語句的程序代碼進行重構。當不同的行為堆砌在一個類中時,很難避免使用條件語句來選擇合適的行為。將行為封裝在一個個獨立的策略類中消除了這些條件語句。
·           過多的算法可能會導致策略對象的數目很大。為了減少系統開銷,通??梢园岩蕾囉谒惴ōh境的狀態保存在客戶端,而將TStrategy實現為可供各客戶端共享的無狀態的對象。任何外部的狀態都由TContext維護。TContext在每一次對TStrategy對象的請求中都將這個狀態傳遞過去。比如范例程序中,我將TSeasonStrategy的外部狀態入住月份、TVIPStrategy的外部狀態VIP卡的種類、TTeamStrategy的外部狀態團隊人數都保存在客戶端,并通過TPriceContext將這些狀態傳遞給銷售策略類。這樣做的好處是銷售策略類變成無狀態的了,它們同時可以被客房結算模塊等其他模塊共享。
·           無論各個具體策略實現的算法是簡單還是復雜, 它們都共享TStrategy定義的接口。因此很可能某些具體策略不會都用到所有通過這個接口傳遞給它們的信息。如果我在范例程序中把TSaleStrategy的接口設計成這樣:
SalePrice(price:Currency;Month:integer;VIP:integer;
                                                 Count:integer):Currency;

其中的一些參數永遠不會被某些具體銷售策略類用到。這就意味著有時TContext會創建和初始化一些永遠不會用到的參數。如果存在這樣問題,又無法使用范例程序中的技巧,那么只能在TStrategy和TContext之間采取緊耦合的方法。


更多相關文章和示例程序源代碼可以到作者網站下載:http://www.liu-yi.net


上一篇:在Delphi中如何維護COM+的狀態信息

下一篇:Delphi7目錄結構----初學者參考

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
學習交流
熱門圖片

新聞熱點

疑難解答

圖片精選

網友關注

亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
久久久久久久成人| 国产精品www| 国产精品久久久久久久久男| 欧美体内谢she精2性欧美| 欧美电影免费观看高清| 91av免费观看91av精品在线| 69久久夜色精品国产69| 成人国产精品免费视频| 久久影视电视剧凤归四时歌| 欧美电影在线观看| 欧美性高潮床叫视频| 欧美激情亚洲国产| 国产日韩专区在线| 98视频在线噜噜噜国产| 97碰碰碰免费色视频| 国产成人鲁鲁免费视频a| 久久精品国产亚洲精品2020| 亚洲图片欧美午夜| 欧美电影在线免费观看网站| 538国产精品一区二区免费视频| 国产日韩专区在线| 亚洲一区二区三区久久| 欧美成人精品在线观看| 亚洲第一网中文字幕| 91精品国产高清自在线看超| 国产视频在线观看一区二区| 国产在线拍揄自揄视频不卡99| 91国语精品自产拍在线观看性色| 欧美疯狂性受xxxxx另类| 国产精品第一第二| 亚洲图片欧洲图片av| 久久视频国产精品免费视频在线| 亚洲第一福利在线观看| 日韩欧美亚洲一二三区| 欧美日韩亚洲一区二区三区| 国产精品网站大全| 国产欧美日韩免费看aⅴ视频| 91精品在线看| 国产视频久久久久久久| 亚洲精品国产精品国自产在线| 欧美性色视频在线| 欧美成年人在线观看| 日韩在线观看免费| 精品亚洲一区二区| 欧美黑人国产人伦爽爽爽| 国产精品久久久久久久av大片| 亚洲精品资源在线| 欧美中文在线观看国产| 精品视频在线播放色网色视频| 国产福利视频一区二区| 国产精品香蕉在线观看| 2019中文在线观看| 久青草国产97香蕉在线视频| 国产主播在线一区| 亚洲人成毛片在线播放| 欧美性猛交xxxx偷拍洗澡| 国产日韩欧美一二三区| 国产精品一区二区三区成人| 欧美另类老肥妇| 久久国产精品首页| 欧美视频中文在线看| 久久成人亚洲精品| 久热精品视频在线免费观看| 日本高清视频精品| 国产主播精品在线| 日韩国产在线看| 亚洲色图偷窥自拍| 久久久国产精品x99av| 日韩一区二区久久久| 一个人看的www欧美| 欧美体内谢she精2性欧美| 按摩亚洲人久久| 亚洲美女精品成人在线视频| 日韩欧美福利视频| 欧美一级电影久久| 国产一区二区三区免费视频| 日韩中文字幕久久| 91豆花精品一区| 一区二区三区回区在观看免费视频| 亚洲免费影视第一页| 神马久久桃色视频| 91美女片黄在线观看游戏| 中文字幕亚洲欧美在线| 亚洲精品免费av| 亚洲天堂av在线免费观看| 日韩精品极品在线观看| 日韩av影视综合网| 亚洲图片欧美日产| 亚洲跨种族黑人xxx| 久久久亚洲福利精品午夜| 伊人久久久久久久久久| 国产精品一区专区欧美日韩| 亚洲精品短视频| 亚洲一区二区中文| 久久久999国产精品| 欧美成人小视频| 97在线看福利| 国产91在线播放九色快色| 亚洲福利在线播放| 91精品国产精品| 91美女福利视频高清| 亚洲色图欧美制服丝袜另类第一页| 在线日韩欧美视频| 中文字幕免费精品一区| 91在线高清免费观看| 亚洲女在线观看| 国产精品久久久久久久app| 亚洲国产97在线精品一区| 国模吧一区二区三区| 97久久精品人人澡人人爽缅北| 欧美黑人巨大精品一区二区| 欧美日韩国产成人| 日本成人精品在线| 国产视频丨精品|在线观看| 91sao在线观看国产| 亚洲情综合五月天| 久久中文字幕在线| 国产精品久久久久久久一区探花| 亚洲品质视频自拍网| 91色在线观看| 国产精品久久久久免费a∨大胸| 在线观看欧美成人| 成人网中文字幕| 久久精彩免费视频| 精品在线小视频| 最新国产精品拍自在线播放| 国产精品福利在线观看网址| 欧美巨猛xxxx猛交黑人97人| 国产精品美女无圣光视频| 亚洲精品福利视频| 欧美成人国产va精品日本一级| 国产精品成熟老女人| 久久久精品久久久久| 亚洲欧美在线一区二区| 国产97人人超碰caoprom| 亚洲精品乱码久久久久久按摩观| 久久亚洲精品网站| 亚洲美女av电影| 国产精品久久久久久搜索| 欧美成人一区二区三区电影| 亚洲理论片在线观看| 国产成人精品久久亚洲高清不卡| 成人在线视频福利| 国产成人免费av| 在线观看亚洲视频| 久久夜精品香蕉| 亚洲大胆人体av| 在线播放亚洲激情| 国产精品美女免费看| 日韩视频免费中文字幕| 欧美视频一二三| 欧美成人一区在线| 欧美亚洲另类视频| 欧美性猛交99久久久久99按摩| 97国产一区二区精品久久呦| 欧美亚洲国产精品| 久久久国产影院| 日韩中文字幕亚洲| 爽爽爽爽爽爽爽成人免费观看| 欧美亚洲成人免费| 日韩美女视频免费在线观看| 美女福利精品视频| 成人国产精品色哟哟| 亚洲永久在线观看|