3

我正在实施一个系统,客户可以使用优惠券获得购买折扣。代金券是否可用于特定购买取决于多种情况。

例如:

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

还有一些更复杂的限制需要检查。如果不满足一项或多项限制,则客户无法使用优惠券,我想告知他/她有关失败的原因,并解释“为什么”他无法使用此优惠券,例如:

“你不能使用这张凭证,因为它已经过时了。”

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

谢谢,

4

3 回答 3

2

就我个人而言,我只会用一种方法来实施检查。凭证进入,错误消息消失(如果有)。

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

如果我们正在谈论大量测试,那么将方法更改为一个类(但再次责任在一个地方,而不是复杂性分散到所有地方)。

只是我的两分钱。

于 2010-01-26T13:57:06.080 回答
0

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

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

于 2010-01-26T23:55:15.647 回答
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 编写了一个示例,但它确实没有增加多少。如果您尝试从抽象的角度进行思考,那么实际的机制就不那么重要了。

于 2010-01-26T22:43:56.653 回答