你的位置:首页 > ASP.net教程

[ASP.net教程]应用接口的策略模式


  最近写了一个应用策略模式的小程序。实现《大话策略模式》里面的商场收银系统。对里面的接口模式进行了一些改装,使得其更具封闭性。

  使用WebForm实现了客户端。先来看看网页部分的主要代码。

  <form id="form1" runat="server">    <div>      <asp:TextBox ID="goodsName" runat="server"></asp:TextBox>      <asp:TextBox ID="goodsPrice" runat="server"></asp:TextBox>      <asp:TextBox ID="goodsNum" runat="server"></asp:TextBox>      <asp:DropDownList ID="cbxType" runat="server">        <asp:ListItem Text="正常" Value="正常"></asp:ListItem>        <asp:ListItem Text="打8折" Value="打8折"></asp:ListItem>        <asp:ListItem Text="满300反100" Value="满300反100"></asp:ListItem>      </asp:DropDownList>      <asp:Button ID="btnOk" runat="server" Text="录入" OnClick="btnOk_click" />      <br />      <asp:TextBox ID="lbxList" runat="server" TextMode="MultiLine"></asp:TextBox>      <%--<asp:Repeater ID="GoodsTable" runat="server">        <HeaderTemplate>          <table class="goods">            <tr>              <th>商品名称</th>              <th>价格</th>              <th>数量</th>              <th>打折方式</th>              <th>总价</th>            </tr>          </table>        </HeaderTemplate>        <ItemTemplate>        </ItemTemplate>      </asp:Repeater>--%>      <br />      <asp:Label ID="lblResult" runat="server" Text="Label" EnableViewState="true"></asp:Label>      <br />      <asp:Button ID="Button1" runat="server" Text="确认支付?" />    </div>  </form>

注释部分暂时还没有实现,先用一个textbox代替了。一个简单的收银页面。后台的事件驱动代码:

 1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Web; 5 using System.Web.UI; 6 using System.Web.UI.WebControls; 7 using CollectionCode; 8 using System.Data; 9 public partial class _Default : System.Web.UI.Page10 {11   double total;12   protected void Page_Load(object sender, EventArgs e)13   {14     if (!IsPostBack) {15       total = 0.0d;16 17     }18     else {19       //total = Convert.ToDouble(lblResult.Text);20     }21     22   }23   public void btnOk_click(object sender, EventArgs e) {24     ICollectionIO CaculateCash=new CashCollectionFactory();25     double totalPrice = 0d;26     CaculateCash.InsertMoney=Convert.ToDouble(goodsPrice.Text) * Convert.ToDouble(goodsNum.Text);    27     CaculateCash.InsertCmd = cbxType.SelectedValue;28     totalPrice = CaculateCash.ResultMoney;29     total = total + totalPrice;30     lbxList.Text+=goodsPrice.Text + " " + goodsNum.Text + " " + cbxType.SelectedValue.ToString() + " "+totalPrice.ToString()+"\n";31     lblResult.Text = total.ToString();32   }  33 }

 

可以看到botton_click部分的代码非常简洁。这是因为我把整个带接口的CollectionCode封装为一个.cs文件放在APP_Code里面了。我改变了书上示范的接口,只传递3个参数:InsertCmd,InsertMoney,返回ResultMoney。而封装了原示例中公开的函数。对于其他.cs外部的程序来说,除了这3个接口数据,其他的内部代码和实现方式是他们不必要也不能知道的。

CollectionCode如下:

 1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Web; 5 /// 将提供UML类图说明结构 6 namespace CollectionCode { 7   public interface ICollectionIO { 8     double InsertMoney { get; set; } 9     string InsertCmd { get; set; }10     double ResultMoney { get; set; }11   }12   class CashSuper {13     public virtual double AcceptCash(double money) { return money; }14   }15   class CashNormal : CashSuper {16     public override double AcceptCash(double money) {17       return money;18     }19   }20   class CashRebate : CashSuper {21     private double RebateValue = 1d;22     public CashRebate(string RebateValueInsert) {23       this.RebateValue = double.Parse(RebateValueInsert);24     }25     public override double AcceptCash(double money) {26       return money * RebateValue;27     }28   }29   class CashReturn : CashSuper {30     private double _moneyCondition = 0.0d;//每moneyCondition钱返回ReturnValue钱31     private double _ReturnValue = 0.0d;32     public CashReturn(string moneyConditionInsert, string ReturnValueInsert) {33       this._moneyCondition = double.Parse(moneyConditionInsert);34       this._ReturnValue = double.Parse(ReturnValueInsert);35     }36     public override double AcceptCash(double money) {37       double _result = money;38       if (_result >= _moneyCondition) {39         _result = _result - Math.Floor(money / _moneyCondition) * _ReturnValue;40       }41       return _result;42     }43   }44   public class CashCollectionFactory:ICollectionIO {45     public double InsertMoney { get; set; }46     public string InsertCmd { get; set; }47     public double ResultMoney { get { return GetResult(InsertMoney, InsertCmd); } set { this.ResultMoney = value; } }48     static CashSuper createCashAccept(string paytype) {49       CashSuper csbuild = null;50       switch (paytype) {51         case "正常": {52             CashNormal csNormal = new CashNormal(); csbuild = csNormal; break;53           }54         case "满300反100": {55             CashReturn csReturn = new CashReturn("300", "100"); csbuild = csReturn; break;56           }57         case "打8折": {58             CashRebate csRebate = new CashRebate("0.8"); csbuild = csRebate;59             //csbuild = new CashRebate("0.8"); 60             break;61           }62         default: break;63       }64       return csbuild;65     }66     double GetResult(double insertMoney, string insertCmd) {67       return createCashAccept(insertCmd).AcceptCash(insertMoney);68     }69   }70   71 }

基本借用了书中示例的策略模式。封装了所有方法。很多时候对于外部程序的请求其实就是一条string命令和几个参数。对于这种请求的处理应该全部在内部进行,而将内部的方法都封装起来。