定 义:它定义了算法家族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化,
不会影响到使用算法的客户。
示例:商场收银系统,实现正常收费、满300返100、打8折.......等不同收费方式
效果图:
结构图:
HTML代码:
<html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>设计模式:策略模式</title> <style type="text/css"> table { width: 300px; height: 250px; border-collapse: collapse; } table, tr, td { border: 1px solid gray; } </style> </head> <body> <form id="form1" runat="server"> <table> <thead> <tr> <td colspan="3"> 商场收银软件 </td> </tr> </thead> <tr> <td> 单价: </td> <td> <asp:TextBox runat="server" ID="txtPrice"></asp:TextBox> </td> <td> <asp:Button runat="server" ID="btnOK" Text="确定" onclick="btnOK_Click" /> </td> </tr> <tr> <td> 数量: </td> <td> <asp:TextBox runat="server" ID="txtNumber"></asp:TextBox> </td> <td> <asp:Button runat="server" ID="Button1" Text="重置" onclick="Button1_Click" /> </td> </tr> <tr> <td> 计算方式: </td> <td> <asp:DropDownList runat="server" ID="ddlCashType"> <asp:ListItem Selected="True">正常收费</asp:ListItem> <asp:ListItem>打8折</asp:ListItem> <asp:ListItem>满300返100</asp:ListItem> </asp:DropDownList> </td> <td> </td> </tr> <tr> <td colspan="3"> <asp:TextBox runat="server" ID=txtMsg TextMode="MultiLine" Rows="8" Columns="30"></asp:TextBox> </td> </tr> <tr> <td> 总计: </td> <td> <asp:Label runat="server" ID="lblTotal"></asp:Label> </td> <td> </td> </tr> </table> </form> </body> </html>
CashContext类:
public class CashContext { CashSuper cs = null; public CashContext(string type) { switch (type) { case "正常收费": cs = new CashNormal(); break; case "满300返100": cs = new CashReturn("300", "100"); break; case "打8折": cs = new CashRebate("0.8"); break; } } public double GetResult(double money) { return cs.AcceptCash(money); } }
CashSuper类:
/// <summary> /// 现金收费抽象类 /// </summary> public abstract class CashSuper { public abstract double AcceptCash(double money); }
CashNormal类:
/// <summary> /// 正常收费子类 /// </summary> public class CashNormal : CashSuper { public override double AcceptCash(double money) { return money; } }
CashRebate类:
/// <summary> /// 打折收费子类 /// </summary> public class CashRebate : CashSuper { private double moneyRebate = 1d; public CashRebate(string moneyRebate) { this.moneyRebate = double.Parse(moneyRebate); } public override double AcceptCash(double money) { return money * moneyRebate; } }
CashReturn类:
/// <summary> /// 返利收费子类 /// </summary> public 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; } }
客户端实现:
protected void btnOK_Click(object sender, EventArgs e) { CashContext csuper = new CashContext(ddlCashType.SelectedValue); string totalPrice = csuper.GetResult(Convert.ToDouble(txtNumber.Text)*Convert.ToDouble(txtPrice.Text)).ToString(); lblTotal.Text = totalPrice; }
策略模式和简单工厂模式区别:
用途不一样,名字就有区别,一把斧头用来砍人就叫凶器,用来砍材就叫伐木斧,用来劈门就叫消防斧,这些模式的名字都是根据具体使用时的场景,联系了现实里某样东西或某种习惯而取得,所以很相似的模式行为有不同叫法很正常。
工厂模式:根据你给出的目的来生产不同用途的斧子,例如要砍人,那么工厂生产砍人斧子,要伐木就生产伐木斧子。
即根据你给出一些属性来生产不同行为的一类对象返回给你。
关注对象创建
策略模式:用工厂生产的斧子来做对应的事情,例如用砍人的斧子来砍人,用伐木的斧子来伐木。
即根据你给出对应的对象来执行对应的方法。
关注行为的选择