โหมดกลยุทธ์ของการเขียนโปรแกรมโหมด Delphi (ต่อ)
หลิวยี่
1.3 การประยุกต์แบบจำลองกลยุทธ์ในระบบการจัดการโรงแรม
ในระบบการจัดการโรงแรม โดยปกติราคาห้องพักจะไม่คงที่ ควรมีกลยุทธ์การขายที่แตกต่างกันสำหรับที่พักนอกฤดูและฤดูท่องเที่ยว ลูกค้าเก่าและลูกค้าใหม่ แขกรายบุคคลและกลุ่ม แน่นอนว่ากลยุทธ์การขายจะเป็นตัวกำหนดข้อเสนอ อย่างไรก็ตาม ระบบใบเสนอราคาตามกลยุทธ์การขายไม่สามารถเชื่อมโยงกับลูกค้ารายใดรายหนึ่งได้ เนื่องจากเพียงการทำให้ระบบใบเสนอราคาตามกลยุทธ์การขายเป็นอิสระเท่านั้นจึงจะสามารถรับประกันการนำกลับมาใช้ใหม่และการบำรุงรักษาได้ ตัวอย่างเช่น: ในด้านหนึ่ง ระบบใบเสนอราคาตอบสนองความต้องการของลูกค้าหลายราย เช่น การสอบถามอัตราค่าห้องพักพิเศษและการชำระราคาห้องพัก ในทางกลับกัน ระบบดังกล่าวตอบสนองความต้องการของการปรับเปลี่ยนกลยุทธ์การขายใหม่ ๆ อย่างต่อเนื่อง ซึ่งสามารถนำกลับมาใช้ใหม่และการบำรุงรักษาได้อย่างแท้จริง . สำหรับข้อกำหนดการออกแบบข้างต้น วิธีที่ดีที่สุดคือเลือกโหมดกลยุทธ์ รูปแบบกลยุทธ์ช่วยให้สามารถเปลี่ยนแปลงอัลกอริธึมได้โดยอิสระจากไคลเอนต์ที่ใช้งาน โปรแกรมตัวอย่างคือโมดูลการสืบค้นราคาที่อยู่อาศัยแบบพิเศษตามแบบจำลองกลยุทธ์ ซึ่งรวมถึงระบบใบเสนอราคาตามกลยุทธ์การขาย และอินเทอร์เฟซการสืบค้นราคาที่อยู่อาศัยแบบพิเศษ แน่นอนว่าอินเทอร์เฟซการสอบถามราคาพิเศษเป็นเพียงหนึ่งในไคลเอนต์ของระบบใบเสนอราคา และระบบใบเสนอราคาก็สามารถใช้งานได้โดยไคลเอนต์อื่น ๆ เช่นกัน การออกแบบโมดูลสอบถามราคาพิเศษแสดงไว้ในรูปที่ 1-6 ประกอบด้วย: · คลาสกลยุทธ์การขาย TSaleStrategy ซึ่งเป็นคลาสพื้นฐานเชิงนามธรรมสำหรับคลาสกลยุทธ์การขายเฉพาะ · 3 หมวดหมู่กลยุทธ์การขายเฉพาะ: TVipStrategy (กลยุทธ์การขายบัตร VIP), TTeamStrategy (กลยุทธ์การขายแบบทีม), TSeasonStrategy (กลยุทธ์การขายตามฤดูกาล) · คลาสใบเสนอราคา TPRiceContext ซึ่งเป็นบริบทในรูปแบบกลยุทธ์นี้และมีการอ้างอิงถึง TStrategy · คลาสไคลเอนต์ TClient คือคลาสแบบฟอร์ม ซึ่งเป็นอินเทอร์เฟซสำหรับการสอบถามราคาบ้าน รูปที่ 1-6 โปรแกรมตัวอย่าง 1-1 ของโมดูลสอบถามราคาห้องพักพิเศษตามรูปแบบกลยุทธ์คือซอร์สโค้ดของหน่วย HotelSaleStrategy หน่วยนี้ประกอบด้วยตรรกะทางธุรกิจของระบบใบเสนอราคาตามกลยุทธ์การขายและนำไปใช้โดยใช้ รูปแบบกลยุทธ์ เนื่องจากเป็นกลยุทธ์การขายที่เป็นนามธรรม TSaleStrategy จึงมีจุดมุ่งหมายที่จะจัดให้มีอินเทอร์เฟซที่ใช้ร่วมกัน ฟังก์ชันนามธรรมเสมือน SalePrice เป็นอินเทอร์เฟซดังกล่าว เนื่องจากกลยุทธ์การขายเฉพาะทั้งสามได้รับการกำหนดตามฤดูกาล การ์ด VIP และขนาดทีม การออกแบบพารามิเตอร์ของอินเทอร์เฟซคลาสพื้นฐาน SalePrice จะต้องตอบสนองความต้องการที่แตกต่างกันของคลาสที่ได้รับทั้งสามคลาส ฟังก์ชัน SalePrice ของ TSaleStrategy มีการประกาศดังนี้: ฟังก์ชัน SalePrice(price:Currency;value:integer):Currency; virtual; abstract; พารามิเตอร์แรกแสดงถึงราคาคงที่ที่เข้ามา และพารามิเตอร์ที่สองแสดงถึงเงื่อนไขพิเศษที่เข้ามา เงื่อนไขจะแตกต่างกันไป สำหรับคลาสที่ได้รับที่แตกต่างกัน ในกลยุทธ์การขายตามฤดูกาล TSeasonStrategy พารามิเตอร์นี้จะแสดงเป็นเดือนที่เช็คอิน ในกลยุทธ์การขายบัตร VIP TVIPStrategy พารามิเตอร์นี้จะแสดงเป็นประเภทของบัตร VIP ในกลยุทธ์การขายของทีม TTeamStrategy พารามิเตอร์นี้จะแสดงเป็น จำนวนคนในทีม เราพบว่าพารามิเตอร์เหล่านี้สามารถใช้ประเภทจำนวนเต็มได้ ดังนั้นในคลาสพื้นฐาน พารามิเตอร์ค่าจะถูกนำมาใช้อย่างชาญฉลาดเพื่อแก้ไขข้อกำหนดพารามิเตอร์ที่แตกต่างกันของคลาสที่ได้รับ ด้วยวิธีนี้ TPriceContext สามารถใส่ข้อมูลในพารามิเตอร์ได้โดยตรง และส่งต่อไปยังการดำเนินการกลยุทธ์การขายต่างๆ เพื่อหลีกเลี่ยงความซ้ำซ้อนของพารามิเตอร์ {TPriceContext }function TPriceContext.GetPrice(price:Currency;value:integer):Currency;begin result:=Strategy.SalePrice(price,value);end;TPriceContext มีบทบาทตามบริบทในโหมดกลยุทธ์นี้ และมีหน้าที่ในการอ้างอิงถึงยอดขาย กลยุทธ์ อินสแตนซ์ที่แตกต่างกันของออบเจ็กต์จะเรียกใช้อินเทอร์เฟซ SalePrice เพื่อกำหนดค่าอัลกอริธึมส่วนลดเฉพาะแบบไดนามิกและส่งคืนราคาขายจริง เนื่องจากเป็นตัวกลางของ TPriceContext ลูกค้าจึงไม่จำเป็นต้องทราบว่ากลยุทธ์การขายเฉพาะเจาะจงถูกนำไปใช้อย่างไร ในทำนองเดียวกัน เมื่อมีการอัปเดตและปรับเปลี่ยนกลยุทธ์การขาย ก็จะไม่ส่งผลกระทบต่อโปรแกรมของลูกค้า โปรแกรมตัวอย่าง 1-1 ซอร์สโค้ดของหน่วย HotelSaleStrategy HotelSaleStrategy; อินเทอร์เฟซ SysUtils, Windows, ข้อความ, คลาส, กราฟิก, การควบคุม, แบบฟอร์ม, ไดอะล็อก; ประเภท TSaleStrategy = คลาส (TObject) ฟังก์ชั่นสาธารณะ SalePrice(price:Currency;value:integer): สกุลเงิน ; เสมือน; นามธรรม; สิ้นสุด; SalePrice(price:Currency;value:integer):Currency; override; end; TTeamStrategy = ฟังก์ชันสาธารณะของคลาส (TSaleStrategy) ราคาขาย(ราคา:สกุลเงิน;มูลค่า:จำนวนเต็ม):สกุลเงิน; แทนที่; สิ้นสุด; (TObject) FStrategy ส่วนตัว: TSaleStrategy; ขั้นตอน SetStrategy (ค่า: TSaleStrategy); ฟังก์ชั่นสาธารณะ GetPrice (ราคา: สกุลเงิน; มูลค่า: จำนวนเต็ม): สกุลเงิน; ฟังก์ชัน TSaleStrategy เขียน TSeasonStrategy.SalePrice(price:Currency;value:integer):Currency;begin //กลยุทธ์การขายตามฤดูกาล {ลด 15% ในเดือนกุมภาพันธ์ มีนาคม และพฤศจิกายน ลด 10% ในเดือนเมษายนและมิถุนายน 8. ส่วนลด 9.5% ในเดือนกันยายน } ค่าตัวพิมพ์ของ 2,3,11:result:=price*0.85; 4,6:result:=price*0.9; 8,9:result:=price*0.95; else result:=price;end;{ TVIPStrategy }ฟังก์ชัน TVIPStrategy.SalePrice(price:Currency;value:integer):Currency;begin //กลยุทธ์การขายบัตรวีไอพี{ 0: ลด 10% สำหรับบัตร VIP Silver 1: ลด 20% สำหรับบัตร VIP Gold 2: ลด 30% สำหรับบัตร VIP Diamond} มูลค่ากรณี 0:result:=price*0.9; 1:result:=price*0.8; :result: =price*0.7; end;end;{TTeamStrategy } ฟังก์ชัน TTeamStrategy.SalePrice(price:Currency;value:integer):Currency;begin //กลยุทธ์การขายแบบทีม ลด 10% สำหรับทีม 3-5 คน; ส่วนลด 20% สำหรับทีม 6-10 คน; ทีม 11-20 คน ลด 20% สำหรับกลุ่มมากกว่า 1 คน } result:=price; if (value<6) และ (value>2) แล้ว result:=price*0.9; if (value<11) และ (value>5) แล้ว result:=price*0.8; 21) และ (value>10) แล้ว result:=price*0.7; if (value>20) แล้ว 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 หน่วยซอร์สโค้ด ClientForm; อินเตอร์เฟสใช้ Windows, ข้อความ, SysUtils, ตัวแปร, คลาส, กราฟิก, การควบคุม, แบบฟอร์ม, ไดอะล็อก, StdCtrls, ExtCtrls, HotelSaleStrategy, ComCtrls, DateUtils; ประเภท TClient = class(TForm) RadioGroup1 : TRAdioGroup; btnตรวจสอบ: TButton; btnExit: TLabel; dtpDate; Label3: TLabel; edtCount: TLabel; ขั้นตอน FormCreate (ผู้ส่ง: TObject); ขั้นตอน btnCheck (ผู้ส่ง: TObject); ขั้นตอน btnExitClick (ผู้ส่ง: TObject); TPriceContext สาธารณะ { ประกาศสาธารณะ } end;var Client: TClient;implementation{$R *.dfm}procedure TClient.FormCreate(Sender: TObject);begin FSeasonStrategy:=TSeasonStrategy.Create; FVIPStrategy:=TVIPStrategy.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 ; .DateTime); สิ้นสุด; 1:เริ่มต้น FPriceSys.Strategy:=FVIPStrategy ; i:=cmbVIP.ItemIndex; end; 300; //ห้องสแตนดาร์ดคลาส A 300 หยวน 1:price:=500; //ห้องมาตรฐานคลาส B คือ 500 หยวน 2:ราคา:=800; // ห้องวีไอพีคือ 800 หยวน 3:ราคา:=1,000; // ห้องบิสซิเนสสวีทคือ 1,000 หยวน 4:ราคา:=2,000; yuanend; edtPrice .Text:=CurrToStr(FPriceSys.GetPrice(price,i));end;ขั้นตอน TClient.FormDestroy (ผู้ส่ง: TObject); เริ่ม FPriceSys.Free; FSeasonStrategy.Free; FVIPStrategy.Free;end; edtCount.Enabled:=false; cmbVIP.Enabled:=false; case RadioGroup1.ItemIndex ของ 0:dtpDate.Enabled:=true; ภาพที่ 1-7 อินเทอร์เฟซที่ใช้งานจริงของโมดูลแบบสอบถามราคาพิเศษ
1.4 สรุปการปฏิบัติ
ผ่านการสาธิตและการวิเคราะห์ตัวอย่างก่อนหน้านี้ เราจะหารือเพิ่มเติมเกี่ยวกับรูปแบบกลยุทธ์ดังต่อไปนี้: · รูปแบบกลยุทธ์จัดเตรียมวิธีในการจัดการชุดของอัลกอริธึม ลำดับชั้นของคลาสกลยุทธ์จะกำหนดชุดของอัลกอริธึมหรือพฤติกรรมที่สามารถนำมาใช้ซ้ำได้สำหรับ TContext คลาสพื้นฐาน TStrategy จะแยกฟังก์ชันทั่วไปในอัลกอริทึมเหล่านี้ และคลาสที่ได้รับจะเสริมความแตกต่างและประเภทของอัลกอริทึมผ่านการสืบทอด และหลีกเลี่ยงการทำซ้ำโค้ด · หากคุณไม่แยกอัลกอริธึมออกจากบริบทที่ใช้อัลกอริธึม และสร้างคลาสที่ได้รับของคลาส TContext โดยตรงซึ่งมีอัลกอริทึม และให้พฤติกรรมที่แตกต่างกัน สิ่งนี้จะฮาร์ดโค้ดพฤติกรรมลงใน TContext และ แยกการใช้งานอัลกอริธึมออกจาก TContext การใช้งานจะผสมกัน ทำให้ TContext เข้าใจยาก บำรุงรักษา และขยาย ผลลัพธ์ที่ได้คือคลาสที่เกี่ยวข้องกันมากมาย ข้อแตกต่างระหว่างคลาสเหล่านั้นคืออัลกอริธึมที่พวกเขาใช้ แน่นอนว่าความสัมพันธ์แบบสืบทอดของคลาสนั้นเป็นการเชื่อมโยงที่แข็งแกร่ง และความสัมพันธ์แบบสืบทอดไม่สามารถเปลี่ยนอัลกอริทึมแบบไดนามิกได้ ในขณะที่ความสัมพันธ์องค์ประกอบของออบเจ็กต์นั้นเป็นการเชื่อมโยงที่อ่อนแอ ด้วยการรวมออบเจ็กต์คลาสกลยุทธ์ อัลกอริธึมสามารถพัฒนาได้อย่างอิสระจากสภาพแวดล้อม (TContext) ที่ใช้อัลกอริธึม · ใช้รูปแบบกลยุทธ์เพื่อปรับโครงสร้างโค้ดโปรแกรมที่ใช้คำสั่งย่อยแบบมีเงื่อนไขจำนวนมาก เมื่อพฤติกรรมที่แตกต่างกันถูกซ้อนกันในชั้นเรียน เป็นการยากที่จะหลีกเลี่ยงการใช้คำสั่งแบบมีเงื่อนไขเพื่อเลือกพฤติกรรมที่เหมาะสม การห่อหุ้มพฤติกรรมในคลาสนโยบายที่แยกจากกันจะช่วยขจัดคำสั่งที่มีเงื่อนไขเหล่านี้ · อัลกอริธึมมากเกินไปอาจส่งผลให้มีออบเจ็กต์นโยบายจำนวนมาก เพื่อลดค่าใช้จ่ายของระบบ สถานะที่ขึ้นอยู่กับสภาพแวดล้อมของอัลกอริธึมมักจะถูกบันทึกไว้บนไคลเอนต์ และ TStrategy จะถูกนำไปใช้เป็นออบเจ็กต์ไร้สัญชาติที่ไคลเอนต์ต่างๆ สามารถใช้ร่วมกันได้ สถานะภายนอกใด ๆ ได้รับการดูแลโดย TContext TContext ส่งผ่านสถานะนี้ในทุกคำขอไปยังวัตถุ TStrategy ตัวอย่างเช่น ในโปรแกรมตัวอย่าง ฉันบันทึกเดือนเช็คอินสถานะภายนอกของ TSeasonStrategy ประเภทการ์ด VIP สถานะภายนอกของ TVIPStrategy และขนาดทีมสถานะภายนอกของ TTeamStrategy บนไคลเอนต์ และส่งสถานะเหล่านี้ไปยังคลาสกลยุทธ์การขายผ่าน TPriceContext ข้อดีของการดำเนินการนี้คือคลาสกลยุทธ์การขายจะกลายเป็นสถานะไร้สถานะ และสามารถใช้ร่วมกันโดยโมดูลอื่นๆ เช่น โมดูลการชำระเงินห้อง · ไม่ว่าอัลกอริธึมที่ใช้โดยแต่ละกลยุทธ์เฉพาะจะเรียบง่ายหรือซับซ้อนก็ตาม อัลกอริธึมทั้งหมดใช้อินเทอร์เฟซที่กำหนดโดย TStrategy ร่วมกัน ดังนั้นจึงมีแนวโน้มว่านโยบายเฉพาะบางอย่างจะไม่ใช้ข้อมูลทั้งหมดที่ส่งผ่านอินเทอร์เฟซนี้ หากฉันออกแบบอินเทอร์เฟซของ TSaleStrategy เช่นนี้ในโปรแกรมตัวอย่าง:
ราคาขาย(ราคา:สกุลเงิน;เดือน:จำนวนเต็ม;วีไอพี:จำนวนเต็ม;
นับ:จำนวนเต็ม):สกุลเงิน;
พารามิเตอร์เหล่านี้บางส่วนจะไม่ถูกใช้ในคลาสกลยุทธ์การขายบางคลาส ซึ่งหมายความว่าบางครั้ง TContext จะสร้างและเริ่มต้นพารามิเตอร์ที่จะไม่ถูกใช้งาน หากมีปัญหาดังกล่าวและคุณไม่สามารถใช้เทคนิคต่างๆ ในโปรแกรมตัวอย่างได้ คุณสามารถใช้วิธีการเชื่อมโยงแบบแน่นหนาระหว่าง TStrategy และ TContext เท่านั้น
บทความที่เกี่ยวข้องเพิ่มเติมและซอร์สโค้ดโปรแกรมตัวอย่างสามารถดาวน์โหลดได้จากเว็บไซต์ของผู้เขียน: http://www.liu-yi.net