引入了策略之后,我们可以按照如下方式进行价格计算:
- /**
- * @author mhcoding
- */
- public class Test {
-
- public static void main(String[] args) {
- UserPayService strategy = new VipPayService();
- BigDecimal quote = strategy.quote(300);
- System.out.println("普通会员商品的最终价格为:" + quote.doubleValue());
-
- strategy = new SuperVipPayService();
- quote = strategy.quote(300);
- System.out.println("超级会员商品的最终价格为:" + quote.doubleValue());
- }
- }
以上,就是一个例子,可以在代码中new出不同的会员的策略类,然后执行对应的计算价格的方法。这个例子以及策略模式的相关知识,读者可以在《如何给女朋友解释什么是策略模式?》一文中学习。
但是,真正在代码中使用,比如在一个web项目中使用,上面这个Demo根本没办法直接用。
首先,在web项目中,上面我们创建出来的这些策略类都是被Spring托管的,我们不会自己去new一个实例出来。
其次,在web项目中,如果真要计算价格,也是要事先知道用户的会员等级,比如从数据库中查出会员等级,然后根据等级获取不同的策略类执行计算价格方法。
那么,web项目中真正的计算价格的话,伪代码应该是这样的:
- /**
- * @author mhcoding
- */
- public BigDecimal calPrice(BigDecimal orderPrice,User user) {
-
- String vipType = user.getVipType();
-
- if (vipType == 专属会员) {
- //伪代码:从Spring中获取超级会员的策略对象
- UserPayService strategy = Spring.getBean(ParticularlyVipPayService.class);
- return strategy.quote(orderPrice);
- }
-
- if (vipType == 超级会员) {
- UserPayService strategy = Spring.getBean(SuperVipPayService.class);
- return strategy.quote(orderPrice);
- }
-
- if (vipType == 普通会员) {
- UserPayService strategy = Spring.getBean(VipPayService.class);
- return strategy.quote(orderPrice);
- }
- return 原价;
- }
通过以上代码,我们发现,代码可维护性和可读性好像是好了一些,但是好像并没有减少if-else啊。
其实,在之前的《如何给女朋友解释什么是策略模式?》一文中,我们介绍了很多策略模式的优点。但是,策略模式的使用上,还是有一个比较大的缺点的:
客户端必须知道所有的策略类,并自行决定使用哪一个策略类。这就意味着客户端必须理解这些算法的区别,以便适时选择恰当的算法类。
也就是说,虽然在计算价格的时候没有if-else了,但是选择具体的策略的时候还是不可避免的还是要有一些if-else。
另外,上面的伪代码中,从Spring中获取会员的策略对象我们是伪代码实现的,那么代码到底该如何获取对应的Bean呢?
接下来我们看如何借助Spring和工厂模式,解决上面这些问题。
工厂模式
(编辑:ASP站长网)
|