据我所知,有两种主要方法可以实现此目的:
getTotal()
。calculate()
方法。我使用一个简单的保险单对象创建了两个示例。每个类都以一些属性初始化,例如premiumRateBase
,brokerFee
,termYears
,effectiveDate
和agentCommissionRate
。计算的列将是按比例分配的premiumRate
,total
或agentCommission
之类的东西。
这是选项1的示例:
component {
// public properties (getters + setters)
property name="premiumRateBase";
property name="brokerFee";
property name="effectiveDate";
property name="termYears";
property name="agentCommissionRate";
function init(
required numeric premiumRateBase,
required numeric brokerFee,
required date effectiveDate,
required numeric termYears,
required numeric agentCommissionRate
) {
// setters
...
return this;
}
function getExpirationDate() {
return dateAdd( 'yyyy', effectiveDate, termYears );
}
function getPremiumRate() {
// run proration and calcuation determination
// based on premiumRateBase, getExpirationDate(), and maybe a few other methods
...
return premiumRate;
}
function getTotal() {
return getPremiumRate() + brokerFee;
}
function getAgentCommission() {
return getPremiumRate() * agentCommissionRate
}
function getAgentCompensation() {
return getAgentCommission() + brokerFee
}
}
在上面的示例中,只要您调用getTotal()
之类的方法,就可以运行计算。这种方法的优点是代码非常简单。这种方法的缺点是,如果需要先运行getTotal()
,getAgentCommission()
然后运行getAgentCompensation()
,则最终会运行大量冗余数学。对于此示例,这并不等于额外的处理时间,但是在更复杂的示例中,我可以看到这加起来。
这是选项2的示例:
component {
// public properties (getters + setters)
property name="premiumRateBase";
property name="brokerFee";
property name="effectiveDate";
property name="termYears";
property name="agentCommissionRate";
function init(
required numeric premiumRateBase,
required numeric brokerFee,
required date effectiveDate,
required numeric termYears,
required numeric agentCommissionRate
) {
// setters
...
// run the calculation
calculate();
return this;
}
// primary calculation method which sets all private properties
function calculate() {
variables.expirationDate = calculateExpirationDate();
variables.premiumRate = calculatePremiumRate();
variables.total = calculateTotal();
variables.agentCommission = calculateAgentCommission();
}
/***************************
Public Getters
***************************/
function getExpirationDate() {
return expirationDate;
}
function getPremiumRate() {
return premiumRate;
}
function getTotal() {
return total;
}
function getAgentCommission() {
return agentCommission;
}
/***************************
Private Calculations
***************************/
private function calculateExpirationDate() {
return dateAdd( 'yyyy', effectiveDate, termYears );
}
private function calculatePremiumRate() {
// run proration and calcuation determination
// based on premiumRateBase, expirationDate and maybe a few other variables
...
return premiumRate;
}
private function calculateTotal() {
return premiumRate + brokerFee;
}
private function calculateAgentCommission() {
return premiumRate * agentCommissionRate;
}
private function calculateAgentCompensation() {
return agentCommission + brokerFee;
}
}
在第二个示例中,我们仅在构造方法calculate()
触发后运行通用init()
方法。我没有包括它,但是如果您曾经通过它们的setter方法更新任何公共属性,则还需要再次运行calculate()
。这种方法的优点是仅在属性更改时才进行计算数学运算。不利之处在于该代码看起来有些复杂且难以阅读。
解决此类问题的最佳实践或正确方法是什么?
答案 0 :(得分:2)
这是一个常见的难题,最终它解决了每次重新计算属性的成本。如果价格便宜,我总是更喜欢使用吸气剂方法。
要考虑的另一个方面是计算属性的陈旧性。选项#2仅在初始化时执行计算,计算之后涉及的属性可能随后会更改。现在,所计算的度量标准将过时。您可以通过重新计算修改指标来修复它。这将进一步增加代码的复杂性。如果此修改未正确封装,则重新计算职责也将与调用方共同承担!
总而言之,对于便宜的计算,我会选择选项#1;对于复杂的计算,我将首先封装修改以确保每次更新都重新计算。