【问题标题】:What Is the Proper Way to Handle Calculated Properties in an Object?处理对象中计算属性的正确方法是什么?
【发布时间】:2019-02-23 02:31:23
【问题描述】:

据我所知,有两种主要方法可以做到这一点:

  • 选项 1: 通过 getter 方法“按需”计算每个属性(例如 getTotal())。
  • 选项 2: 在构造时填充所有计算的属性,并在公共属性更改时使用 通用 calculate() 方法。

我使用一个简单的保险单对象创建了两个示例。每个类都使用一些属性进行初始化,例如 premiumRateBasebrokerFeetermYearseffectiveDateagentCommissionRate。计算的列将是按比例分配的 premiumRatetotalagentCommission

这是选项 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;
    }


}

在第二个示例中,我们只在构造方法init() 触发后运行通用calculate() 方法。我没有包括这个,但是如果您通过它们的 setter 方法更新任何公共属性,您还需要再次运行calculate()。这种方法的优点是计算数学仅在属性更改时发生。缺点是代码看起来更复杂,更难阅读。

解决此类问题的最佳实践或正确方法是什么?

【问题讨论】:

    标签: class oop methods


    【解决方案1】:

    这是一个常见的困境,最终它解决了每次重新计算属性的成本。如果它便宜,我总是更喜欢 getter 方法。

    另一个需要考虑的维度是计算属性的陈旧性。选项 #2 仅在初始化时执行计算,并且计算中涉及的属性可能会在之后发生变化。计算出的指标现在将过时。您可以通过重新计算修改指标来修复它。这将进一步增加代码的复杂性。如果这个修改没有很好地封装,重新计算的责任也将与调用者分担!

    总之,对于便宜的计算,我更喜欢选项 #1,对于复杂的计算,我会首先封装修改以确保每次更新时重新计算。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多