这次是DesignMode系列的第二期,是书上第二章,关于策略模式的讲解,用一个实例-商店收银系统来说明这个模式的优势。
开发软件Visual Studio2013,WPF开发。
打开VS新建项目,选择WPF应用,客户端代码可能存在问题,水平有限,高手忽略。
首先新建一个抽象类CashSuper.cs
abstract class CashSuper
{
public abstract double AcceptCash(double money);
}
再新建三个子类实现CashSuper,分别为CashNormal.cs,CashRebate.cs,
CashReturn.cs
class CashNormal:CashSuper
{
public override double AcceptCash(double money)
{
return money;
}
}
class CashRebate :CashSuper
{
private double moneyRebate;//定义打折数量
//构造方法中,实例化时,传入打折率
public CashRebate(string moneyRebate)
{
this.moneyRebate = double.Parse(moneyRebate);
}
public override double AcceptCash(double money)
{
return money*moneyRebate;
}
}
class CashReturn:CashSuper
{
private double moneyCondition=0.0d;//分别输入满多少返利多少
private double moneyReturn=0.0d;
public CashReturn(string moneyCondition, string moneyReturn)
{
this.moneyCondition = double.Parse(moneyCondition);
this.moneyReturn = double.Parse(moneyReturn);
}
public override double AcceptCash(double money)
{
double result = money;
if (money > moneyCondition)
{
result = money - Math.Floor(money/moneyCondition)*moneyReturn;
}
return result;
}
}
最后建立类CashContext.cs,在其中实例化对象,结合了工厂模式,客户端与后台逻辑基本分开,使得客户端只需要认识CashContext这个类就行。
class CashContext
{
private CashSuper cs=null;
public CashContext(string type)
{
switch (type)
{
case "正常收费":
CashNormal cs1= new CashNormal();
cs = cs1;
break;
case "满300返200":
CashReturn cs2 = new CashReturn("300","200");
cs = cs2;
break;
case "打8折":
CashRebate cs3 = new CashRebate("0.8");
cs = cs3;
break;
}
}
public double GetResult(double money)
{
return cs.AcceptCash(money);
}
}
客户端代码
public partial class MainWindow : Window
{
private double totalPrice = 0.0d;
public MainWindow()
{
InitializeComponent();
InitOther();
}
void InitOther()
{
SinglePriceText.Text = "0";
NumberText.Text = "0";
TotalPriceLabel.Content = "0";
RecordList.Items.Clear();
if (CalcMethod.Items.Count >= 1)
return;
CalcMethod.Items.Add("正常收费");
CalcMethod.Items.Add("打8折");
CalcMethod.Items.Add("满300返200");
CalcMethod.SelectedIndex = 0;
}
private void ConfirmBtn_Click(object sender, RoutedEventArgs e)
{
CashContext cashContext = new CashContext(CalcMethod.SelectedItem.ToString());
double ItemTotalPrices = 0.0d;
ItemTotalPrices = cashContext.GetResult(double.Parse(SinglePriceText.Text)*int.Parse(NumberText.Text));
totalPrice += ItemTotalPrices ;
RecordList.Items.Add( " 单价:" + SinglePriceText.Text + " 数量:" + NumberText.Text + " " +
CalcMethod.SelectedItem + " 合计:" + ItemTotalPrices+"\n");
TotalPriceLabel.Content = totalPrice;
}
private void ResetBtn_Click(object sender, RoutedEventArgs e)
{
InitOther();
}
}
WPF界面设计
<Window x:Class="CashApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="商场收银系统" Height="450" Width="425">
<Grid>
<TextBlock HorizontalAlignment="Left" Margin="26,35,0,0" TextWrapping="Wrap" Text="单价:" VerticalAlignment="Top"/>
<TextBlock HorizontalAlignment="Left" Margin="26,65,0,0" TextWrapping="Wrap" Text="数量:" VerticalAlignment="Top"/>
<TextBlock HorizontalAlignment="Left" Margin="26,105,0,0" TextWrapping="Wrap" Text="计算方式:" VerticalAlignment="Top"/>
<TextBlock HorizontalAlignment="Left" Margin="26,332,0,0" TextWrapping="Wrap" Text="总计:" VerticalAlignment="Top"/>
<TextBox Name="SinglePriceText" HorizontalAlignment="Left" Height="23" Margin="67,30,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="196" HorizontalContentAlignment="Right"/>
<TextBox Name="NumberText" HorizontalAlignment="Left" Height="23" Margin="67,60,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="196" HorizontalContentAlignment="Right"/>
<ListBox Name="RecordList" Margin="26,151,25,119" />
<Label Name="TotalPriceLabel" Content="" HorizontalAlignment="Left" Margin="86,332,0,0" VerticalAlignment="Top" Width="165" Background="{DynamicResource {x:Static SystemColors.MenuBrushKey}}" HorizontalContentAlignment="Right" Height="26"/>
<ComboBox Name="CalcMethod" HorizontalAlignment="Left" Margin="101,105,0,0" VerticalAlignment="Top" Width="120"/>
<Button Name="ConfirmBtn" Content="确认" HorizontalAlignment="Left" Margin="317,32,0,0" VerticalAlignment="Top" Width="75" Click="ConfirmBtn_Click"/>
<Button Name="ResetBtn" Content="重置" HorizontalAlignment="Left" Margin="317,62,0,0" VerticalAlignment="Top" Width="75" Click="ResetBtn_Click"/>
</Grid>
</Window>
下面是测试图:
如果需要添加新的返利方法,添加新的类就行,算法的变化,将不影响客户端。