我今天遇到了这个代码,并想知道我们可以通过哪些方式对其进行优化。
显然,该模型很难改变,因为它是遗产,但有兴趣获得意见。
更改了一些名称并模糊了一些核心逻辑以保护。
private static Payment FindPayment(Order order, Customer customer, int paymentId)
{
Payment payment = Order.Payments.FindById(paymentId);
if (payment != null)
{
if (payment.RefundPayment == null)
{
return payment;
}
if (String.Compare(payment.RefundPayment, "refund", true) != 0 )
{
return payment;
}
}
Payment finalPayment = null;
foreach (Payment testpayment in Order.payments)
{
if (testPayment.Customer.Name != customer.Name){continue;}
if (testPayment.Cancelled)
{
continue;
}
if (testPayment.RefundPayment != null)
{
if (String.Compare(testPayment.RefundPayment, "refund", true) == 0 )
{
continue;
}
}
if (finalPayment == null)
{
finalPayment = testPayment;
}
else
{
if (testPayment.Value > finalPayment.Value)
{
finalPayment = testPayment;
}
}
}
if (finalPayment == null)
{
return payment;
}
return finalPayment;
}
将其设为维基,以便代码爱好者可以回答而无需担心问题。
答案 0 :(得分:2)
if (testPayment.Customer.Name != customer.Name){continue;}
开始时不应该这样 - 当然,针对任何给定订单的所有付款都与同一客户有关?
我根本不喜欢这个功能,如果我通过了pay_id传递,那么我只希望获得特定付款,或者无效...这些搜索都没有... < / p>
听起来我觉得你需要考虑重新设计很多代码,我认为它远远超出了这个特定的功能......
答案 1 :(得分:1)
它将高度依赖数据。您需要使用“典型”数据集对其进行分析,找出瓶颈,然后根据您的配置文件数据考虑适当的优化。
答案 2 :(得分:1)
如果您可以向Payment
类添加成员,请添加didRefund
布尔值,只要RefundPayment
字符串设置为“退款”,该布尔值就会设置为true。这允许您避免字符串比较。
在循环之前,如果你像这样初始化finalPayment
:
finalPayment = new Payment;
finalPayment.Value = -1.0e12
然后你可以避免循环中的空测试。 (假设没有一个客户正在支付十亿美元的负债)
答案 3 :(得分:1)
第一次测试(if (payment.RefundPayment == null)
)是多余的。
使用String.Compare
的第二个测试使用空字符串。您可以在foreach
循环中使用此“比较”的第二位使用此“优化”。
答案 4 :(得分:1)
你可以将其中一个条件移动到它自己的函数中,因为它重复了两次(测试它和它的相反)。您还可以将条件推到一起并将整个循环包装在第一个条件中。这样你只有一个函数的退出点。如果这看起来不可管理,你可以将foreach-loop
包装成一个函数,然后就这样调用它。
private static boolean IsRefundPayment(Payment payment) {
return payment.RefundPayment != null && String.Compare(payment.RefundPayment, "refund", true) == 0;
}
private static Payment FindPayment(Order order, Customer customer, int paymentId) {
Payment payment = Order.Payments.FindById(paymentId);
if (payment == null || IsRefundPayment(payment)) {
foreach (Payment testpayment in Order.payments) {
if (testPayment.Customer.Name == customer.Name && !testPayment.Cancelled && !IsRefundPayment(payment)
&& (testPayment.Value > payment.Value)) {
payment = testPayment;
}
}
}
return payment;
}