最近在重构公司的电子商务网站,其中有个打折消费的功能.这里简单介绍下,比如,网站搞活动买二送一(以下称A),或者买二瓶其中价格低的一瓶半价(以下称B),.
最初的设计是很粗糙的,因为之前网站是没有活动,后来增加一个活动,现在又要增加新的活动.从一开始的直接写代码,到后来的if else 判断打折条件,到现在又要添加新的打折,觉得这样的代码写的很粗糙,有种不爽的感觉.
现在刚好有机会重构这里,就大概设计一下,也好让这里更面向对象一点.之前没有这样设计是因为根本没有想到会有这么多的改变,呵呵,还好可以重构,这个也是不断学习的过程.
好了,废话不说了,贴下设计类图.
之前有考虑使用接口,因为促销A和促销B,都要实现方法OperateShippingCart,但是后来一想,这2次促销方式,其实都可以统称促销方式,也就是说他们是"is-a"的关系,这样的话使用抽象类比较好.定义一个抽象类Sales,促销A和促销B继承他,并重写他的促销方法.
然后使用简单工厂方法,根据不同的要求创建不同的实例,这样也使用了多态的特性.
if (sale != null)//如果有促销活动
{
sale.Operate += AddPresent;//这里使用了委托
save = sale.CountShoppingCart(list);
}
这样就抛弃了起初很多if..else..判断不同的促销方式了,要新增加促销方式的话,使其直接继承Sale,然后重写OperateShippingCart就可以了.
下面说下,这里我使用了委托.使用委托是因为,促销方式A和B的功能只是计算打折后的价格,但是要操作购物车,比如购物满2瓶,就要再赠送他1瓶,或者购物满500元,也要送一瓶酒.这里就需要直接操作购物车了.这里我的促销方式是放在另外一个工程里的,并在website里引用了它,当然不能在OperateShippingCart里直接操作购物车,这样就要引用website导致循环引用了.
后来想了下,这个还是使用委托的好.
委托是对函数签名的封装,事件是委托的一种特殊形式.
要使用委托,首先要定义委托,然后定义事件,在class中判断事件如果不为空,则调用事件订阅者的方法.当然要操作购物车是需要传递参数的,给委托传递参数,只要让参数继承自EventArgs就可以了,这里还遇到个问题,就是Sale里定义了委托,但是在子类中并不能调用它,会出现错误,后来百度知,需要在父类中定义一个虚方法调用委托,然后在子类中重写并调用这个方法就搞定了.
{
int prodID;
public int ProdID
{
get { return prodID; }
set { prodID = value; }
}
int type;
public int Type
{
get { return type; }
set { type = value; }
}
int quantity;
public int Quantity
{
get { return quantity; }
set { quantity = value; }
}
}
{
public delegate void OperatShoppingCartEventHandle(object sender, ShoppingCartEventArgs args);
public event OperatShoppingCartEventHandle Operate;
/// <summary>
/// 对购物车中的产品进行折扣处理
/// </summary>
/// <param name="list"></param>
/// <returns>返回节省下来的金额</returns>
public abstract decimal CountShoppingCart(List<CShoppingCartItem> list);
/// <summary>
/// 调用委托
/// </summary>
/// <param name="sender"></param>
/// <param name="args"></param>
public virtual void Event(object sender, ShoppingCartEventArgs args)
{
if (Operate != null)
{
Operate(sender, args);
}
}
{
ISale 成员 同样的一瓶买几送几
这里不得不佩服下园子里那些强人,能把文章写的很长很详细而且面面俱到,真是让人学习的楷模.而自己写的文章总觉得拖泥带水,一带而过,呵呵
还要再学习啊,大家共勉