我有这个很长的方法:
public decimal decDiscount(QuoteData quoteData)
{
if (TotalChapter7(quoteData) >= 7499)
return 5300;
else if (TotalChapter7(quoteData) >= 7449)
return 5300;
else if (TotalChapter7(quoteData) >= 7399)
return 5250;
else if (TotalChapter7(quoteData) >= 7349)
return 5200;
else if (TotalChapter7(quoteData) >= 7299)
return 5200;
else if (TotalChapter7(quoteData) >= 7249)
return 5150;
else if (TotalChapter7(quoteData) >= 7199)
return 5100;
else if (TotalChapter7(quoteData) >= 7149)
return 5100;
else if (TotalChapter7(quoteData) >= 7099)
return 5050;
//...
else if (TotalChapter7(quoteData) >= 1199)
return 1100;
else if (TotalChapter7(quoteData) >= 1149)
return 1100;
else if (TotalChapter7(quoteData) >= 1099)
return 1050;
else if (TotalChapter7(quoteData) >= 1049)
return 1000;
else
return 0;
}
具有重复模式,可以通过以下Excel工作表进行说明:
......>>>>
从最高“费用”(7499)开始,每项声明的费用下降50。但是,回报(或“折扣价”)每100个保持相同(费用两个50滴),然后一个回报减少50个(费用减少50个),然后重复。
你可以看到我的方法很长(我在7049和1249之间遗漏了)。我有什么办法可以缩短这个吗?
感谢。
答案 0 :(得分:3)
你们真的过于复杂了。尝试使用整数运算来解决这个问题的任何方法都是一个坏主意。看看对于一群非常聪明的人(我们都非常聪明,不是吗?)来说,首先要做到这一点是多么困难。它真的很难被发现,它真的很难理解,很难做到正确,而且这是一个难以维护。
您需要一种易于理解且易于维护的方法。看看你的原帖,你有一个规则的英文描述。
然而,回报(或“折扣价”)每100个保持相同(费用两个50滴),然后一个回报减少50个(费用减50个),然后重复。
代码实际上写了自己:
public int GetFeeFromQuoteData(QuoteData quoteData) {
int fee = 5300;
int difference = 7449 - TotalChapter7(quoteData);
bool isTwoStep = true;
while (difference > 0) {
if (isTwoStep) {
difference -= 50;
}
else {
difference -= 100;
}
fee -= 50;
isTwoStep = !isTwoStep;
}
return fee;
}
答案 1 :(得分:2)
这些价格&折扣 DATA !绝不应将数据编译成代码
我不会将代码构建到代码中,我会构建基础定价结构(它们可能会与价格下降有关,但不太可能改变整体定价结构)。
我有价格&反映此结构的易于更改的地方(例如数据库,xml文件)中的相关折扣。
public class Pricing
{
private List<Tuple<decimal, decimal>> pricePoints= new List<Tuple<int, decimal>> discountRanges();
public Pricing()
{
// These hard coded values would be replaced by logic to load from file.
pricePoints.Add(Tuple.Create(7499, 5300));
pricePoints.Add(Tuple.Create(7399, 5250));
pricePoints.Add(Tuple.Create(7349, 5200));
pricePoints.Add(Tuple.Create(7249, 5150));
. . .
pricePoints.Add(Tuple.Create(1049, 1000));
}
public decimal GetDiscount(QuoteData quoteData)
{
var price = TotalChapter7(quoteData);
foreach(var point in pricePoints)
{
if(price >= point.Item1)
return point.Item2;
}
// If we're here it implies there were no matching points
return 0;
}
}
如果您将代码构建到代码中,并且他们更改了代码,则您需要更改代码 将数据放在一个文件中,在运行时加载一次文件,他们可以更改价格,你只需要更改文件。
反驳“这里显然是商业规则”评论
不包括销售点的折扣(一个优惠2个,此商品优惠10%等),基本上有三种方式可以计算整体费用或折扣的折扣(任何一种都可以与首选客户折扣相结合) )。
客户决定使用哪一个(或多个)是业务规则,是的,规则需要在代码中表示。
但是,无论使用哪种规则,实际值都是数据,并且该数据应永远(禁止高度特殊情况)在代码中。
答案 2 :(得分:1)
也许这会有所帮助:
List<Tuple<int, int>> _FeeToPrice = new List<Tuple<int, int>> {
new Tuple<int,int>(7499,5300),
new Tuple<int,int>(7399,5250),
...
new Tuple<int,int>(1049,1000)
};
public decimal decDiscount(QuoteData quoteData)
{
var processedQuoteData = TotalChapter7(quoteData);
var tuple = _FeeToPrice.FirstOrDefault(x => processedQuoteData >= x.Item1);
if (tuple != null)
return tuple.Item2;
return 0;
}
编辑:
_FeeToPrice
结构可以从文件或数据库或其他来源加载,这样可以更容易地更正返回值
答案 3 :(得分:1)
分析计算的工作公式如下:
int calcDiscount(int p)
{
int s = (7500/50) - (p+1) / 50;
int k = s / 3;
int j = s % 3;
return 5300 - 100*k - (j == 2 ? 50 : 0)
}
工作测试用例(用Java编写):
for (p = 7499; p >= 1000; p -= 50)
{
System.out.println (p+ " " + calcDiscount(p));
}
说明:首先你会发现当前价格从最大值(7499)开始有多少下降步骤,然后你知道你必须每三步降低贴现值100,但是如果你是当前三联的最后一步,你必须放弃它再增加50个。
答案 4 :(得分:0)
下面的伪代码:
Dictionary<Int, Int> getDiscounts(int startFee, int startDiscount, int endFee)
{
Dictionary <Int, Int> quoteDictionary = new Dictionary<Int, Int> ();
for(int i = 0; i++; startFee >= endFee)
{
startFee -= 50;
if(i != 0)
{
startDiscount -= 50;
}
if(i == 2)
{
i = -1;
}
quoteDictionary[startFee] = startDiscount;
}
return quoteDictionary;
}
您可以这样称呼它:
Dictionary <Int, Int> prices = getDiscounts(7499, 5300, 1049);
int quote = TotalChapter7(quoteData);
int roundedQuote = quote - ((quote % 50) + 1);
int discountedFee = prices[roundedQuote];
答案 5 :(得分:0)
我不知道这是否适合您,但您可以使用字典,并按照上面示例中的降序对键进行排序。
我还没有测试过,但这样的事情可能有用:
public int GetNumber(int value)
{
//initialize a dictionary to hold pairs of numbers
var ranges = new SortedDictionary<int, int>
{
{ 25, 250 },
{ 50, 500 },
{ 75, 750 }
};
//sort the dictionary in descending order and return the first value
//that satisfies the condition
return ranges.OrderByDescending(p => p.Key)
.FirstOrDefault(p => value >= p.Key).Value;
}
答案 6 :(得分:-1)
尝试使用字典,试图做一个例子,但我不经常使用C#,所以纠正代码上不正确的东西,只是试着理解:
public decimal decDiscount(QuoteData quoteData)
{
int result = 0; //if it doesn't match to any value on the dictionary it will return 0
Dictionary<int, int> quotes = new Dictionary<int, int();
quotes.add(7499, 5300); // not sure if that's how you add values to a dictionary
...
quotes.add(1049, 1000);
for(Entry<int, int> element in quotes) //not sure about the enhanced for too hehehe, not using C# for a while
{
if(TotalChapter7(quoteData) >= element.key() && element.value > result)
{
result = element.value(); //don't break cause you have to test the entire list for acurracy
}
}
return result;
}