设计模式--策略模式
最最近公司在做一个电子商务网站,之前的网站需求还没有完毕,设计上出现很多的不足.但是时间紧急.只好按照粗糙的设计进行开发.目前项目已经到了一期后期阶段,好吧,原来的设计人员放手不干了,烂摊子接下来由我来收拾..............
言归正传,之前的设计,一直忽略了打折算法.设计当时说的是为了尽快完工,好吧,为了尽快完工,忽略了打折,那么.后期还是需要实现打折的.但是打折算法有三个技术难点需要考虑,并且提出解决方案.
1.打折的话,只是部分商品打折,并不是所有商品打折. -----打折的商品如何计算?不打折的呢如何计算?
2.假设中秋节开设了促销活动,促销活动当天,所有商品都打折. ------所有商品都打折,那么上面的1问题不就是矛盾了吗?
3.打折是根据商品的类型进行的,还是根据商品单个进行的?
其实,对于上面的问题,前辈们已经给出了具体的解决方案,这里,我们假设商品较少,使用当个商品进行打折.如果商品较多的话可是使用商品的类型进行打折.
前辈们提出了策略模式,其实策略模式也就是封装一个具体的算法类,通过切换算法的实现允许程序在运行的时候修改一个对象的行为(打折).
下面我们看一下策略模式的UML静态结构图.
1.Context依赖于Strategy累的抽象.
2.Strategy由具体的ConcreateStrategyA、ConcreateStrategyB、ConcreateStrategyC实现。
So,我们是不是看出点什么来了。
打折算法的实现思路:
1.封装一个打折算法----PriceManage类。用来实现具体的打折算法。
2.Product类-----商城中需要打折的商品。
3.提供一个借口IDiscountStrategy,抽象出打折的策略,具体怎么打折由商品提供,比如打几折。
下面我们看看Code
public interface IDiscountStrategy { decimal ApplyExtraDiscountsTo(decimal OriginalSalePrice); }
这个接口就用来实现不同打折的策略,这是策略模式的一种应用。这个模式允许我们在运行的时候更改不同的算法实现。在本例子中,Price类将会根据不同的产品来实现不同的打折策略。
//打几折 public class TradeDiscountStrategy : IDiscountStrategy { public decimal ApplyExtraDiscountsTo(decimal OriginalSalePrice) { decimal price = OriginalSalePrice; price = price * 0.6M; return price; } } //不打折 public class NullDiscountStrategy : IDiscountStrategy { public decimal ApplyExtraDiscountsTo(decimal OriginalSalePrice) { return OriginalSalePrice; } }
不打折的情况也算是一种打折,其他的商品打折可能是7折,不打折的情况就是10折。
接下来,我们来看看PriceManage类的实现
public class PriceManage { private IDiscountStrategy _discountStrategy = new NullDiscountStrategy(); private decimal _rrp; private decimal _sellingPrice; public Price(decimal RRP, decimal SellingPrice) { _rrp = RRP; _sellingPrice = SellingPrice; } public void SetDiscountStrategyTo(IDiscountStrategy DiscountStrategy) { _discountStrategy = DiscountStrategy; } public decimal SellingPrice { get { return _discountStrategy.ApplyExtraDiscountsTo(_sellingPrice); } } public decimal RRP { get { return _rrp; } } public decimal Discount { get { if (RRP > SellingPrice) return (RRP - SellingPrice); else return 0;} } public decimal Savings { get{ if (RRP > SellingPrice) return 1 - (SellingPrice / RRP); else return 0;} } }
Price类在设计中就是用了“依赖倒置原则”,因为它没有采用某一个具体的打折实现算法,而且依赖于接口抽象,至于之后到底会哪种的打折算法,其实是由商品的类型来决定的。
我们还是继续的看,现在看看Product类。
public class Product { public int Id { get; set; } public string Name { get; set; } public Price Price { get; set; } }
到此打折策略使用的策略模式已经实现了。现在总结为一下。
策略模式:封装一个具体的算法类,通过切换算法的实现允许程序在运行的时候修改一个对象的行为