2010-01-26 61 views
3

我正在实施一个系统,客户可以使用凭证获取购物折扣。如果凭证可以用于某种购买取决于几种情况。如何解释具有复杂限制的操作失败

例如:

  • 适当的优惠券代码 - 是代码是否正确?
  • 有效范围 - 凭证仍然有效吗?
  • 凭证可以与购买类型一起使用吗?
  • 允许组合 - 优惠券是否可以与其他优惠券结合使用?
  • 更多...

也有一些更多的是需要检查复杂的限制。如果一个或多个限制不满足,客户无法使用优惠券,我想通知他/她有关“无法使用”的解释“为什么”,例如:

“You can'不要使用这张优惠券,因为它已经过时了。“

我现在的问题是:你会如何执行检查?
在自己的类中实现每个限制,链接它们并抛出异常? (这里的问题,可能会执行几个相同的数据库查询) 在一个单一方法中实现所有限制? (真的,为什么?) 一般来说,如果实施一种机制,您必须通知客户有关如果将复杂限制应用于某个操作时失败的详细信息?

谢谢,

回答

2

就我个人而言,我会在一个方法中执行检查。凭证进入,出错消息(如果有的话)。

这将保持所有代码隐藏在该方法后面,并使维护变得容易。一个地方检查是否出现问题,一个地方修改添加新东西等

如果我们正在谈论大量的测试,而不是改变方法到一个类(但再次责任在一个地方,没有复杂性散布在各地)。

只是我的两分钱。

0

我将抽象的意图,以便它并不重要它是如何实现的,还是怎么着源代码的组织。在基本层面上,您拥有的是一组检查器,生成一系列失败解释。

的伪代码将主要是:

let reasons be a new, empty collection of failure reasons 
let checkers be the list of relevant checkers 

for each checker in checkers 
    if checker passes, continue 
    if checker fails, add explanation to reasons 

if number of reasons is zero, 
    voucher is valid, success 
if number of reasons > zero, 
    the voucher is invalid, format each element in reasons for display to the user 

有了这个逻辑,不要紧的跳棋是如何组织的,只要他们能够获得通过的这部分代码在一个列表。你可以有一个单一的方法与许多检查,可能会增加很多原因。你可以有许多类,每个检查器列表中有一个实例。至关重要的是,实际的检查人员与此逻辑脱钩,随时可以使用不同的检查人员(考虑业务规则变化或不同地区的不同规则)。

根据您的语言,这至少会涉及抽象用于检查者的类型。

从那开始。如果您发现相同的数据库查询,则开始考虑用于运行检查程序集的缓存。

至于跳棋是如何在源级别上组织的......没关系。只有抽象才会。一旦你提供了一个可以隐藏起来的抽象级别,细节就相当灵活了。

优点:

  • 执行检查不关心实际的,具体的检查(这可能会改变根据业务规则)位。
  • 无论您想要如何组织跳棋,您都可以组织跳棋:在一个源文件中一起定义跳棋,或者根据其他方案进行分组。它还允许自由分离出一个检查器来进行测试。
  • 集合和漂亮的格式化只需执行一次,无论检查的类型或数量如何。

缺点:

  • 这需要时间的前期做设计抽象的一份体面的工作。这可能会在稍后得到回报。
  • 有一层间接性可能使其更难以理解,并追查正在进行的实际检查。灵活性不利于可理解性。这些是你必须考虑的情况。在我看来,优惠券的规则似乎是随着时间的推移可能会改变的东西,这里的抽象并不难理解,所以我认为这是值得的。

我花时间在Java中编写了一个例子,但它确实没有增加太多。如果试图从抽象的角度思考,实际的机制并不重要。

0

我最近处理了一个类似的问题,检查使用一步结帐页面下单。最后,我们发现生成一个包含所有相关“问题”(我们用简单的类包含代码,显示消息等)的数组而非描述遇到的第一个问题的字符串更有用。

这适用于返回一组相关问题的单个检查器方法。主要的检查器方法调用更具体的检查器方法来构建数组。如果其他人已经失败,它可以选择跳过一些检查。