2013-10-07 20 views
1

我在采访中被要求实施业务规则是代理链是否合适

需求变更。他们总是这样:

  1. 评估20%的费用低于$ 100,000的任何数额。
  2. 评估10万美元至500,000美元之间任何金额的10%费用。
  3. 评估5%的费任何量高于$ 500,000

计算费用的任意量x。

例如:给定600,000美元的发票,费用应该是65,000美元。

给定50,000美元的发票费用应该是10,000美元。

给定200,000美元的发票,费用应该是30,000美元。

我用CofR,但面试官然后问,如果他们超过3个条件,像他们n我会创建n类来处理每个请求。

他们是一个更好的方法来解决这个问题,因为写了一个非常长的递归函数来检查每个条件。

回答

2

当链的成员有明显不同的规则时,CoR会有所帮助,但在这种情况下,所有规则基本相同(如果金额超过X,则收取一定的百分比)。而不是独立的阶级,只是有一个结构类似类,用于保存的最低金额和百分比,以及另外一个,查找相应的费用:

class FeeSchedule { 
    static class Entry implements Comparable<Entry> { 
     int threshold; 
     int percentage; 

     int compareTo(Entry other) { 
      // sort by percentage, descending 
     } 

    SortedSet<Entry> feeTable; 

    int calculateFee(int invoiceAmount) { 
     for(Entry e : feeTable) 
      if(invoiceAmount > e.threshold) 
       return (invoiceAmount * e.percentage); 

     // error condition; return 0? 
    } 
} 
+0

你在这里得到了令人敬畏的逻辑,但是如何获得每个条目的百分比。我似乎无法就此作出结论。 – Ayodeji

+0

@Ayodeji这是一个基本的草图。吸气剂,构造剂等 – chrylis

2

我猜测,面试官暗示像责任链模式这样的事情对于像这样的问题有点过分设计。还有一种观点认为,你的实现类实际上会有相同的责任,因为他们都会根据给定的输入计算一个数量,只是使用不同的参数。

我可能会用两个简单的类来做到这一点。人们可以根据输入值计算百分比费率,并且可以使用此费率返回费用金额。

如果您需要添加第四个条件,您只需将其添加到包含费率计算的类中即可。对于这样一个简单的问题,我不明白为什么它需要比这更复杂。

编辑:

我正沿着相同的路线思想为@chrylis在那里会是通过处理率的有序列表来进行计算的一类。

class Rate { 
    int rangeSize; 
    double commission; 

    Rate(int rangeSize, double commission){ 
     this.rangeSize = rangeSize; 
     this.commission = commission; 
    } 

    int computeForAmount(int amount) { 
     if (amount <= 0) { 
      return 0; 
     } 
     return (int) (Math.min(amount, this.rangeSize) * this.commission); 
    } 
} 

class FeeCalculator { 

    List<Rate> rates = Arrays.asList(
      new Rate(100, 0.2), 
      new Rate(400, 0.1), 
      new Rate(500, 0.05)); 

    int calculateCommission(int startingAmount) { 
     int commission = 0; 
     int remainingAmount = startingAmount; 

     for (Rate rate : this.rates) { 
      commission += rate.computeForAmount(remainingAmount); 
      remainingAmount -= rate.rangeSize; 
     } 

     return commission; 
    } 

} 

我承认,我并不完全高兴通过调用rate.rangeSize打破封装,但它确实表明我试图阐明设计。

+0

能否请你放下你的解释在伪代码什么的,我似乎并不了解你提出的逻辑。谢谢。 – Ayodeji

+0

我明白了,这完全消除了我的递归,并且使得它比程序更加面向对象。 @chrylis点现在更清晰。哥们,谢啦。新包包。 – Ayodeji

0

我认为在这种情况下,一个简单的策略模式应该足够了。喜欢的东西:

interface FeeAssessor { 
    public double assessFee(double invoice); 
} 

FeeAssessor feeAssessor = new FeeAssessor() { 
     // logic goes here 
    }; 

double calculateFee(double invoice) { 
    return feeAssessor.assessFee(invoice); 
} 

对于您提出了一个简单的商业逻辑,我认为这将是容易实现这一切一个assessFee()函数内。你可以实现不同的(简单的)并根据需要换出“战略”对象。如果费用评估算法取决于彼此独立的独立多个变化因素,那么您可以进一步将它们分成多个策略方法。