技术开发 频道

实战迷你版“一卡通”交易系统

  类似的代码解释过很多遍了,不多说,它就是一个登记容器,所有的具体策略都在这里登记,然后提供给工厂方法模式。策略工厂如代码清单35-8所示。

  代码清单35-8 策略工厂

public class StrategyFactory {
    
//策略工厂
    public static IDeduction getDeduction(StrategyMan strategy){
        IDeduction deduction
= null;
        
try {
            deduction
= (IDeduction)Class.forName(strategy.getValue()).newInstance();
        }  
catch (Exception e) {
            
// 异常处理
        }
        
return deduction;
    }
}

  一个简单的工厂,根据策略管理类的枚举项创建一个策略对象,简单而实用,策略模式的缺陷也弥补成功,那~~这么复杂的系统怎么让高层模块访问?你看不出复杂?那是因为我们写的都是快乐路径,太多情况都没有考虑,在实际项目中有仅仅就并发处理和事务管理这两部分就够让你头疼了。既然系统很复杂,是不是需要封装一下,我们请出门面模式由它进行封装,如代码清单35-9所示。

  代码清单35-9 扣款模块封装

public class DeductionFacade {
    
//对外公布的扣款信息
    public static Card deduct(Card card,Trade trade){
        
//获得消费策略
        StrategyMan reg = getDeductionType(trade);
        
//初始化一个消费策略对象
        IDeduction deduction = StrategyFactory.getDeduction(reg);
        
//产生一个策略上下问
        DeductionContext context = new DeductionContext(deduction);
        
//进行扣款处理
        context.exec(card, trade);
        
//返回扣款处理完毕后的数据
        return card;
    }
    
//获得对应的商户消费策略
    private static StrategyMan getDeductionType(Trade trade){
        
//模拟操作
        if(trade.getTradeNo().contains("abc")){
            
return StrategyMan.FreeDeduction;
        }
else{
            
return StrategyMan.SteadyDeduction;
        }
    }
}

  这次为什么要先展示代码而后写类图呢?那是因为这段代码比写类图更能让你理解。读者注意一下getDeductionType方法,这个方法在实际的项目中是存在的,但是与上面的写法有天壤之别,为啥?在实际项目中,数据库中保存了策略代码与交易编码的对应关系,直接通过数据库的SQL语句就可以返回对应的扣款策略。这里我们采用大家最熟悉的条件转移来实现,也是比较清晰和容易理解的。

  可能读者要问了,在门面模式中已经明确地说明,门面类中不允许有业务逻辑存在,但是你这里还是有了一个getDeductionType方法,它可代表的是一个判断逻辑呀,这是为什么呢?是的,该方法完全可以移到其他Hepler类中,由于我们是示例代码,暂没有明确的业务含义,故编写在此处,读者在实际应用中,请把该方法放置到其他类中。

0
相关文章