为什么要使用设计模式因为我们项目的需求总是在变化,为了应对这种变化,我们的代码可以很方便的进行解耦和扩展。如果你能保证代码一次写完就不会变,那你想怎么写就怎么写。如何判断哪些地方需要用到设计模式在我们的实现中,有些代码写了一次以后基本上不会改,或者不需要扩展,比如一些工具类。其中一些会经常变化,大部分设计模式都应用在需求会变化的这部分。分析这些代码会发生怎样的变化,选择合适的设计模式来优化这部分代码。以促销活动的需求为例。为了促进产品的销售,各大电商平台在平时或部分节假日都会撤掉一些促销活动来刺激用户消费。活动种类可能有所不同,具体如下:满减满40020代金券优惠、玛莎拉蒂5元金券优惠、满减10折、满20折、满200减10等.有的可以叠加使用,有的只能单独使用。以上需求的简单实现看似比较简单,但如果考虑到我们不可能一次定义所有类型的促销活动,我们可能会在以后随时添加新的类型。要保证功能扩展能够轻松实现,那就比较麻烦了。Spring框架使用的9种设计模式总结。你知道吗?刚拿到需求的时候,不用想那么多。撸起袖子就是一个操作:publicclassOrderPromotion{publicBigDecimalpromotion(Orderorder,int[]promotions){for(intpromotion:promotions){switch(promotion){case1://计算这种折扣后的价格突破;case2://calculatethepricebreakafterthistypediscount;case3://calculatepricebreakafterthistypediscount;//....}}returnorder.getResultPrice();}}单从功能实现来说,上面的代码已经完成了基本的功能。但是上面的代码也是致命的。虽然看起来很简单,但只是因为大部分功能都被注释代替了。如果换成实际代码,一个方法可能有几千行。尤其是当我们需要添加新的促销时,需要在switch中添加新的类型,这对开发来说是一个灾难,维护这些代码也是一件麻烦事。优化一:单一职责原则在上面的代码中,promotion(...)方法直接完成了所有的工作,但是在我们实际实现中,最好让一个方法职责单一,只完成某个功能,所以这里我们将折扣类型判断和价格计算分开:);休息;case3:calculate3(order);break;//morepromotion}}returnorder.getResultPrice();}publicvoidcalculate1(Orderorder){//计算使用折扣后的价格1}publicvoidcalculate2(Orderorder){//计算使用后的价格discount2}publicvoidcalculate3(Orderorder){//计算折扣后的价格3}//morecalculate}这里我们把判断折扣类型和计算价格分开了,大大减少了promotion(...)方法的代码量并提高了代码的可读性。面对象设计六大原则之一:单一职责原则,本文也推荐大家阅读。优化二:策略模式上面的优化代码,提高了原代码的可读性,但是仍然没有解决原OrderPromotion代码爆炸的问题。为了解决这个问题,我们希望将计算代码和当前代码分开。我们首先能想到的是定义一个类,然后将计算代码复制到这个类中,需要的时候调用。这的确是分居,但完全是治标不治本。添加新促销时,必须更改两个类。因此,我们希望能够将不同的促销活动分开执行,让每个活动的执行都是分开的,修改不会影响到其他人。基于此,我们可以选择策略模式来实现。策略模式策略模式的思想是将每一种算法封装到一个单独的类中,对一组算法有一个通用的接口,使它们可以相互替代。策略模式最大的特点是可以在不影响客户端的情况下改变算法,从而改变不同的功能。publicclassOrderPromotion{publicBigDecimalpromotion(Orderorder,int[]promotions){for(intpromotion:promotions){switch(promotion){case1:newPromotionType1Calculate(order);break;case2:newPromotionType1Calculate(order);break;case3:newPromotionType1Calculate(order);break;//morepromotion}}returnorder.getResultPrice();}}上面的代码明显简化了很多。现在如果需要添加促销,只需要定义一个促销类,实现PromotionCalculation接口,添加到switch中即可。优化三:工厂模式上面的代码虽然分离了促销活动的实现,但是OrderPromotion还是在变化的,每次新增活动或者下线都需要修改这个类。现在我们希望OrderPromotion保持不变,并将PromotionCalculation的实例化分开。创建类显然是使用工厂设计模式。OrderPromotionpublicclassOrderPromotion{publicBigDecimalpromotion(Orderorder,int[]promotions){for(intpromotion:promotions){PromotionFactory.getPromotionCalculate(promotion).calculate(order);}returnorder.getResultPrice();}}类的创建交给用于实施的工厂。publicclassPromotionFactory{publicstaticPromotionCalculategetPromotionCalculate(intpromotion){switch(promotion){case1:returnnewPromotionType1Calculate(order);break;case2:returnnewPromotionType1Calculate(order);break;case3:returnnewPromotionType1Calculate(order);break;/}}/morepromotionFactory使用之后,OrderPromotion类不需要改变。每次增加新的推广,只需要在工厂类中添加即可。优化四:配置+反射上面代码的问题在于,每次需要添加新的推广,工厂类中的代码还是要修改的。这里我们通过在配置文件中加入反射来解决。定义映射配置文件mapping.properties1=design.order.PromotionType1Calculate2=design.order.PromotionType2Calculate3=design.order.PromotionType3CalculatePromotionFactorypublicclassPromotionFactory{privatestaticMap
