现在电子商务针对商品都有佣金的计算,佣金的算法也会跟着商品或商品分类变化而变化。本文姑且佣金发生在订单商品上,在本文将会讲讲佣金计算程序的演变过程.
先给大家看 一个图
在这个图中,佣金计算是按照商品所属分类计算的。佣金类型分为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();