大話設計模式筆記——策略模式
阿新 • • 發佈:2018-12-03
本篇內容為博主個人在學習《大話設計模式》(程傑 著)過程中的測試隨筆,在此給各位程式設計新手作為學習參考,畢竟網上深入學習的資料對於瓶頸期的新人大多不太友好,我會盡量詳細的展示並解釋每一個細節,也歡迎大家對我的不足給予批評指正。
這週一直在加班,今天終於早點下班了,繼續把上週學習的內容記錄一下。
本篇以商場收銀軟體應對多變的折扣策略為例,為我們展示如何把變化的演算法封裝起來,讓它與業務隔離,同時減小程式的耦合度,讓演算法的變化不會影響到使用演算法的客戶。
專案目錄如下
一、運算業務基類
結算業務類基類(BaseCharge)定義了一個計算金額的虛方法(CountMoney())。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace StrategyTest.Business { class BaseCharge { /// <summary> /// 計算金額 /// </summary> /// <param name="TotalPrice">應收款</param> /// <returns>實收款</returns> public virtual double CountMoney(double TotalPrice) { return TotalPrice; } } }
二、按折扣計算金額演算法類
繼承結算業務類基類(BaseCharge),重寫基類方法CountMoney(),實現對應收款的打折後實付款演算法。
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace StrategyTest.Business { class ChargeByDiscount : BaseCharge { /// <summary> /// 折扣率 /// </summary> private double DiscountRate; /// <summary> /// 建構函式,將傳入的折扣率賦值 /// </summary> /// <param name="discountRate">折扣率</param> public ChargeByDiscount(string discountRate) { DiscountRate = Convert.ToDouble(discountRate); } /// <summary> /// 重寫基類計算價格的方法 /// </summary> /// <param name="TotalPrice">應收款</param> /// <returns>實付款</returns> public override double CountMoney(double TotalPrice) { return TotalPrice * DiscountRate; } } }
三、按滿減計算金額演算法類
繼承結算業務類基類(BaseCharge),重寫基類方法CountMoney(),實現對應收款的滿減後實付款演算法。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StrategyTest.Business
{
class ChargeByFullSub : BaseCharge
{
/// <summary>
/// 條件金額
/// </summary>
public double ConditionalMoney = 0;
/// <summary>
/// 減免金額
/// </summary>
public double SubMoney = 0;
/// <summary>
/// 建構函式
/// </summary>
/// <param name="conditionalMoney">條件金額</param>
/// <param name="subMoney">減免金額</param>
public ChargeByFullSub(double conditionalMoney, double subMoney)
{
ConditionalMoney = conditionalMoney;
SubMoney = subMoney;
}
/// <summary>
/// 重寫基類計算價格的方法
/// </summary>
/// <param name="TotalPrice">應收款</param>
/// <returns>實付款</returns>
public override double CountMoney(double TotalPrice)
{
return TotalPrice - Math.Floor(TotalPrice / ConditionalMoney) * SubMoney;
}
}
}
四、按原價計算金額演算法類
繼承結算業務類基類(BaseCharge),重寫基類方法CountMoney(),實現對應收款的原價計算實付款演算法。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StrategyTest.Business
{
class ChargeByNormal : BaseCharge
{
/// <summary>
/// 重寫基類計算價格的方法
/// </summary>
/// <param name="TotalPrice">應收款</param>
/// <returns>實付款</returns>
public override double CountMoney(double TotalPrice)
{
return TotalPrice;
}
}
}
五、Context上下文
定義一個演算法例項oCharge ,通過簡單工廠模式獲取相應的演算法類例項,呼叫各個演算法類重寫的基類計算金額方法來計算應付款。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace StrategyTest.Business
{
class ChargeContext
{
/// <summary>
/// 定義一個演算法例項
/// </summary>
BaseCharge oCharge = null;
/// <summary>
/// 建構函式,同時利用簡單工廠模式,獲取對應的計算類例項
/// </summary>
/// <param name="CountType">計算型別字串</param>
public ChargeContext(string CountType)
{
switch (CountType)
{
case "正常收費":
this.oCharge = new ChargeByNormal();
break;
case "打八折":
this.oCharge = new ChargeByDiscount("0.8");
break;
case "滿400減50":
this.oCharge = new ChargeByFullSub(400, 50);
break;
}
}
/// <summary>
/// 獲取最終實付款金額
/// </summary>
/// <param name="TatolPrices">應收款</param>
/// <returns>實付款</returns>
public double GetResultPrices(double TatolPrices)
{
return oCharge.CountMoney(TatolPrices);
}
}
}
六、WinFrom後臺程式碼
WinFrom介面如下
WinFrom後臺程式碼
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using StrategyTest.Business;
namespace StrategyTest
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btn_Count_Click(object sender, EventArgs e)
{
double oTotalPrices = 0;
//簡單工廠寫法
//BaseCharge oCharge = ChargeContext.InstantiationCharge(cmb_CountType.SelectedItem.ToString());
//oTotalPrices = oCharge.CountMoney(Convert.ToDouble(txt_UnitPrice.Text.Trim()) * Convert.ToDouble(txt_Num.Text.Trim()));
//策略加簡單工廠寫法
ChargeContext oChargeContext = new ChargeContext(cmb_CountType.SelectedItem.ToString());
oTotalPrices = oChargeContext.GetResultPrices(Convert.ToDouble(txt_UnitPrice.Text.Trim()) * Convert.ToDouble(txt_Num.Text.Trim()));
lab_Total.Text = oTotalPrices.ToString();
}
}
}
個人理解策略模式主要用來封裝各種業務規則,比如ORM框架中可用於實現封裝不同型別資料庫的增刪改查方法等,目前對這個演算法的理解還是不太透徹,希望以後遇到實際需求時,能夠用得上它。