电子商务之佣金计算

现在电子商务针对商品都有佣金的计算,佣金的算法也会跟着商品或商品分类变化而变化。本文姑且佣金发生在订单商品上,在本文将讲讲佣金计算程序的演变过程.

先给大家看 一个图


在这个图中,佣金计算是按照商品所属分类计算的。佣金类型分为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);

 

}

}

问题出来

1PaySum应该是买此商品的支付费用。不应该出现在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; }

        }

    }

那现在CashSuperAcceptCash方法参数应该是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,ConfigurationElementConfigurationCollection]

 

现在修改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 

posted @ 2008-09-25 11:48  roboth  阅读(3632)  评论(7)    收藏  举报