简体   繁体   English

从Java的构造函数内部调用私有方法

[英]Calling private methods from inside the constructor in Java

I have the following class: 我有以下课程:

package com.tesco.demandforecasting.group8.choprachap7;

import java.util.ArrayList;

import com.tesco.demandforecasting.group8.utils.MathOperUtils;
import com.tesco.demandforecasting.group8.utils.RegressionUtils;

import lombok.Getter;

/**
 * This class if used to find seasonality factor of each period, as explain in
 * the chapter See https://kelley.iu.edu/mabert/e730/Chopra-Chap-7.pdf for the
 * explanation
 */
@Getter
public class ChopraChap7SeasonalFactorsCalculator {

    private double[] regressionParams;

    private int sales_size;
    private int periodicity;

    private ArrayList<Integer> sales;
    private ArrayList<Double> deseasonalisedData;
    private ArrayList<Double> deseasonalisedDemandUsingRegression;
    private ArrayList<Double> seasonalityFactors;

    public ChopraChap7SeasonalFactorsCalculator() {

        this.sales = new ArrayList<>();
        this.deseasonalisedData = new ArrayList<>();
        this.deseasonalisedDemandUsingRegression = new ArrayList<>();
        this.seasonalityFactors = new ArrayList<>();

        this.sales.add(8000);
        this.sales.add(13000);
        this.sales.add(23000);
        this.sales.add(34000);
        this.sales.add(10000);
        this.sales.add(18000);
        this.sales.add(23000);
        this.sales.add(38000);
        this.sales.add(12000);
        this.sales.add(13000);
        this.sales.add(32000);
        this.sales.add(41000);

        this.sales_size = sales.size();
        this.periodicity = 4;

        calculateSeasonalityFactors();
    }


    private void calculateSeasonalityFactors() {

        .......
        .......

        this.seasonalityFactors = seasonalityFactors;
        this.deseasonalisedDemandUsingRegression = deseasonalisedDemandUsingRegression;
        this.deseasonalisedData = deseasonalisedData;

    }

}

I want to expose the class fields to external classes, using their respective getters. 我想使用各自的getter将类字段公开给外部类。 But, the problem is that those fields attain any value only after the ChopraChap7SeasonalFactorsCalculator() method is called. 但是,问题在于,只有在调用ChopraChap7SeasonalFactorsCalculator()方法之后,这些字段才能获得任何值。 So, what I have done here is call the method as soon as an object of the class is created. 因此,我在这里所做的就是在创建类的对象后立即调用该方法。 Of course, this will work, but is this good design pattern? 当然,这会起作用,但这是一种好的设计模式吗?

Supposing I would not have called the method from the constructor. 假设我不会从构造函数中调用该方法。 So, if we have the following code is some other class: 因此,如果我们有以下代码,则是其他一些类:

ChopraChap7SeasonalFactorsCalculator calc = new ChopraChap7SeasonalFactorsCalculator();
calc.getDeseasonalisedData();

This will return to me any empty array list. 这将返回任何空数组列表。 How do I ensure that the method is called before any field is accessed? 如何确保在访问任何字段之前调用该方法?

What would be the best design pattern in my case? 就我而言,最佳的设计模式是什么?

Of course, this will work, but is this good design pattern? 当然,这会起作用,但这是一种好的设计模式吗?

This is a very correct design. 这是一个非常正确的设计。 You delegate a part of the constructor logic into a private method to make things clearer. 您可以将构造函数逻辑的一部分委托给私有方法,以使事情更清楚。

This will return to me any empty array list. 这将返回任何空数组列表。 How do I ensure that the method is called before any field is accessed? 如何确保在访问任何字段之前调用该方法?

Your fear about someone changes something in the constructor may be true for any methods or chunks of code. 您担心有人会在构造函数中进行某些更改可能适用于任何方法或代码块。
But applications are not designed to check that each component does what we expect from it. 但是,应用程序并非旨在检查每个组件是否达到了我们的期望。 This is the unit tests role to assert that the actual behavior is which one expected. 这是单元测试角色,用于断言实际行为是预期的行为。

So write an unit test for the ChopraChap7SeasonalFactorsCalculator constructor and in this test assert that all getters return the expected values once the object is created. 因此,为ChopraChap7SeasonalFactorsCalculator构造函数编写一个单元测试,并在此测试中断言,一旦创建对象,所有吸气剂都会返回期望值。
If someone modifies the constructor in an incorrect way, the test will fail and the build too. 如果有人以错误的方式修改了构造函数,则测试将失败,构建也将失败。 You have your way to make sure things are as expected now. 您可以通过自己的方式确保一切都按预期进行。

I think that's pretty fine. 我认为那很好。 The constructor is there to create a useful object. 构造函数在那里创建有用的对象。 If you are sure the object cannot be used without these being set there is no reason why not to set them in the constructor. 如果确定没有设置这些对象就无法使用该对象,则没有理由不在构造函数中进行设置。

If you check https://docs.oracle.com/javase/tutorial/java/javaOO/constructors.html 如果您检查https://docs.oracle.com/javase/tutorial/java/javaOO/constructors.html

A class contains constructors that are invoked to create objects from the class blueprint. 一个类包含构造函数,这些构造函数被调用以根据该类蓝图创建对象。

You have added the fields but you don't have a working object without these being set and apparently you know the values already. 您已经添加了字段,但是没有设置这些字段就没有工作对象,而且显然您已经知道这些值。 The best way to do it would be leave these in the constructor. 最好的方法是将这些保留在构造函数中。 If there are some unknown values or requirements in order to create an instance of that class you can consider Factory pattern or something but in your case constructor usage is just fine. 如果有一些未知的值或要求来创建该类的实例,则可以考虑使用Factory模式或其他方式,但是在这种情况下,使用构造函数就可以了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM