阅读内容 

电子商务之佣金计算

[日期:2008-09-26] 来源:  作者: [字体: ]
     现在电子商务针对商品都有佣金的计算,佣金的算法也会跟着商品或商品分类变化而变化。本文姑且佣金发生在订单商品上,在本文将会讲讲佣金计算程序的演变过程.
  
  先给大家看 一个图
  
  
  在这个图中,佣金计算是按照商品所属分类计算的。佣金类型分为A,B,C类型。
  
  计算佣金也就是计算 A,B,C类型.它们都接受商品的信息,计算后得出佣金,既然有共有的东西,我们就应该抽象出来。代码如下
  
  abstract public class CashSuper
  
  {
  
   abstract public decimal AcceptCash(ProductInfo info)
  
  }
  
  那A,B,C对应的类,也要继承CashSuper[A,B,C其实是算法,我们把算法做为对象来操作]
  
  public class CashA:CashSuper
  
   {
  
   public override decimal AcceptCash(ProductInfo info)
  
   {
  
   ///.code here
  
   }
  
  }
  
  
  
  
  
  
  
  
  
  
  
  public class CashB:CashSuper
  
   {
  
   public override decimal AcceptCash(ProductInfo info)
  
   {
  
   ///.code here
  
   }
  
   }
  
  public class CashC:CashSuper
  
   {
  
   public override decimal AcceptCash(ProductInfo info)
  
   {
  
   ///.code here
  
   }
  
  }
  
  现在客户端的程序如下
  
  class app
  
  {
  
  static void Main()
  {
  
   ProductInfo info=new ProductInfo
  
  info.Quantity=10;
  
  info.PaySum=1000.3m;
  
  info.Price=23.232m;
  
  CashSuper cs=new CashA();
  
  decimal servicefee= cs.AcceptCash(info);
  
  
  
  }
  
  }
  
  问题出来
  
  1:PaySum应该是买此商品的支付费用。不应该出现在ProductInfo里,应该是OrderItem的一个属性。
  
  2:在客户端程序里涉及到对象的创建,为什么不用工厂。
  
  为了解决第一个问题,也是为抽象类接受泛泛的参数,所以我们有必要设计一个超类.来满足子类所需的信息参数。超类的代码如下
  
  public class CashBase
  
   {
  
   private decimal _money;
  
   private decimal _price;
  
   private int _quantity;
  
  
  
   public decimal Money
  
   {
  
   get { return _money; }
  
   set { _money = value; }
  
   }
  
   public decimal Price
  
   {
  
   get { return _price; }
  
   set { _price = value; }
  
   }
  
   public int Quantity
  
   {
  
   get { return _quantity; }
  
   set { _quantity = value; }
  
   }
  
   }
  
  那现在CashSuper中AcceptCash方法参数应该是CashBase
  
  abstract public decimal AcceptCash(CashBase cb );
  
  解决第二个问题,我们就用简单工厂吧。
  
  public sealed class DataAccess {
  
  
  
  
  
   CashSuper cs=null;
  
   private DataAccess() { }
  
   public static CashSuper CreateCash(type) {
  
   switch(type)
  
   {
  
   case “A”:
  
   cs=new CashA();
  
   break;
  
   case “B”:
  
   cs=new CashB();
  
   break;
  
   case “C”:
  
   cs=new CashC();
  
   break;
  
  }
  
   return cs;
  
   }
  
  
  
   }
  
  }
  
  现在的客户端的代码如下
  
  class app
  
  {
  
   static void Main()
  
  {
  
   CashBase cb=new CashBase();
  
   cb.Price=2.3m;
  
   cb.Quantity=2;
  
   cb.Moeny=300.2m;
  
   CashSuper cs=DataAccess.CreateCash(“A”);
  
   cs.AcceptCash(cb);
  
  }
  
  }
  
  
  
  写到这里感觉已经解决问题了,可是仔细想想,又有点问题,上面提到过A,B,C其实是算法。我们把它当成对象看待,所以用了简单工厂。可是工厂是创建型模式,用来创建对象的。
  
  面对算法的千变万化,每次的扩展我们都的去修改工厂。好像不是最好的方法。
  
  现在我们把工厂重构一下!并给它换个名字吧
  
  public class CashContext
  {
  
   private CashSuper _cs;
  
   public CashContext(CashSuper cs)
  
   {
  
   this._cs=cs;
  
  }
  
  public decimal GetResult(CashBase cb)
  
  {
  
   _cs.AcceptCash(cb);
  
  }
  
  }
  
  再看看客户端的代码
  
  class app
  
  {
  
  static void Main()
  {
  
   CashBase cb=new CashBase();
  
   cb.Price=2.3m;
  
   cb.Quantity=2;
  
  cb.Moeny=300.2m;
  
  
  
  CashSuper cc=null;
  
  switch(type)
  
  {
  
   case “A”:
  
   cs=new CashA();
  
   break;
  
   case “B”:
  
   cs=new CashB();
  
   break;
  
   case “C”:
  
   cs=new CashC();
  
   break;
  
  
  
  }
  
  CashContext cc=new CashContext(cs);
  
  cc.GetResult()
  
  }
  
  }
  
  
  
  仔细看看上面的代码,我们发现现在客户端得判断佣金算法的类型了。这当然不是我们想要的。为了不上客户端判断[switch语句],我们就责任转交给CashContext里
  
  public class CashContext
  {
  
   private CashSuper _cs;
  
   public CashContext(string type)
  
   {
  
   switch(type)
  
  {
  
   case “A”:
  
   _cs=new CashA();
  
   break;
  
   case “B”:
  
   _cs=new CashB();
  
   break;
  
   case “C”:
  
   _cs=new CashC();
  
   break;
  
  
  
  }
  
  
  
  }
  
  public decimal GetResult(CashBase cb)
  
  {
  
   _cs.AcceptCash(cb);
  
  }
  
  }
  
  现在客户端的代码如下
  
  class app
  
  {
  
   static void Main()
  
   { CashBase cb=new CashBase();
  
   cb.Price=2.3m;
  
   cb.Quantity=2;
  
   cb.Moeny=300.2m;
  
   CashContext cc=new CashContext(“A”);
  
   cc.GetResult();
  
  
  
  }
  
  }
  
  现在不管是CashContext还是客户端都的去switch啊。有没有办法不switch呢。
  
  其实还 有更好的办法,那就是使用反射机制。
  
  现在我们在web.config设计这样的节点
  
   <configSections>
  
   <section name="ServiceFeeOperate" type="自己写吧"/>
  
   </configSections>
  
  <ServiceFeeOperate>
  
  <ServiceFeeType>
  
   <add name=”A” value=”CashA” />
  
   <add name=”B” value=”CashC” />
  
   <add name=”C” value=”CashC” />
  
  </ServiceFeeType>
  
   <SpecialMerchant>
  
  
  
  当然了你还的开发节点程序[ConfigurationSection,ConfigurationElement,ConfigurationCollection等]
  
  
  
  现在修改CashContext如下
  
  public class CashContext
  {
  
   private CashSuper _cs;
  
  private readonly string path = ConfigurationManager.AppSettings["ServiceFeeAssembly"];
  
   public CashContext(string type)
  
   {
  
  ServiceFeeSection section = (ServiceFeeSection)ConfigurationManager.GetSection("ServiceFeeOperate");
  
  string classname=section. ServiceFeeType[type].Value
  
  classname= path+”.”+classname
  
  _cs= (CashSuper)Assembly.Load(path).CreateInstance(className);
  
  
  
  }
  
  public decimal GetResult(CashBase cb)
  
  {
  
   _cs.AcceptCash(cb);
  
  }
  
  }
  
  好了,佣金的算法就写到这吧,高人拍砖吧。
  
   YInguang
  
   20080925  
阅读:
录入:blue1000

推荐 】 【 打印
相关新闻      
本文评论       全部评论
发表评论
  • 尊重网上道德,遵守中华人民共和国的各项有关法律法规
  • 承担一切因您的行为而直接或间接导致的民事或刑事法律责任
  • 本站管理人员有权保留或删除其管辖留言中的任意内容
  • 本站有权在网站内转载或引用您的评论
  • 参与本评论即表明您已经阅读并接受上述条款


点评: 字数
姓名:
Advertisement
内容查询


Advertisement