在构造函数中调用方法是一种好习惯吗?

时间:2020-01-11 01:53:07

标签: java constructor

我有以下要自动生成premium值的类:

public class MedicalPolicy implements PolicyType {

    private int id;
    private LocalDate effective;
    private LocalDate expiry;
    private String policyNo;
    private double premium;
    private ArrayList<Beneficiary> beneficiaries;

    public MedicalPolicy(LocalDate effective,LocalDate expiry,ArrayList<Beneficiary> beneficiaries){
        this.id=0;
        this.effective=effective;
        this.expiry=expiry;
        this.beneficiaries=beneficiaries;
        this.premium=getPremiumByCalculation();
        this.policyNo= Integer.toString(LocalDate.now().getYear()) + "-Medical-" + Integer.toString(id);
    }

    private double getPremiumByCalculation(){
        //do some calculation based on some criteria
    }
}

使用像我一样的方法来计算溢价是一种好习惯,还是有更好的方法?

3 个答案:

答案 0 :(得分:1)

不,这是一个糟糕的主意

不要在部分构造的对象上调用方法。您可能认为您可以认为它已经足够构造,或者如果您查看代码,就可以看到它可能会起作用,但是其他所有人都必须经过推论,然后进行维护。

Swing要做很多,而且一团糟。导致各种NullPointerException

可以确定方法,但不要使其成为同一实例的实例方法。此代码的一个特殊问题是,看起来premium每次更改都需要更新,这将非常脆弱。

答案 1 :(得分:0)

在我看来,这没有错。您可以测试它是否可以与简单的JUnit文件一起使用,但是如果可以,则继续。

答案 2 :(得分:0)

这还不行,因为字段(甚至最后一个字段!)可能没有您期望的值。有点鸡蛋和鸡蛋的情况:您的方法将假定对象已完全构造,但是,直到方法完成,才可能完全构造对象。

通常的替代方法是静态方法。这避免了整个hullabaloo。这确实意味着您必须传递运行此计算所需的实际信息,但这实际上是一件好事:它可以使您更清楚需要哪些信息,并且更易于测试。

我注意到您的字段不是最后的字段;我假设确定“溢价”的计算至少取决于这些非最终字段之一。在这种情况下,您是否考虑过该字段更新时会发生什么?通常,解决此问题的最简单方法是使所有字段都成为最终字段,并将其变为不可变对象,巧妙地避开“但是如果更新了该怎么办?”问题。

第二种简单的解决方案是完全删除premium字段,然后每次重新计算。如果这全部是数学运算(指数和对数的乘积和应用,等等),那么,CPU的运行速度将非常快。实际上,CPU可以在一次内存查询中执行300到500条指令(我大大简化了,因为相邻字段的内存查询通常来自同一缓存页面,因此有效地释放了内存,但是,嘿,如果必须首先获取该缓存页面,那么一旦我们已经获取了500个周期,为什么还要担心另外4个周期,对吧?也许让该对象占用的内存少一倍,实际上可以节省缓存查找稍后,因此速度更快–没有探查器报告,不要猜测,去编写更简单的代码,而完全摆脱premium听起来像在这里会更简单。每个人都叫getPremiumByCalculation( )(并将其重命名为getPremium())。

相关问题