0

I would like to refactor the following code:

public Credito(String numero, String titular, LocalDate fechacaducidad, double credito, int marcainternacional,
            String nombreentidad, int ccv) {
        mNumero = numero;
        mTitular = titular;
        mFechaDeCaducidad = fechacaducidad;
        mCredito = credito;
        mMovimientos = new Vector<Movimiento>();
        mMarcaInternacional = marcainternacional;
        setmNombreEntidad(nombreentidad);
        setmCCV(ccv);
    }

public Credito(String numero, String titular, LocalDate fechacaducidad, int tipo, int marcainternacional,
        String nombreentidad, int ccv) {
    mNumero = numero;
    mTitular = titular;
    mFechaDeCaducidad = fechacaducidad;
    mTipo = tipo;
    mCredito = calcularCredito(mTipo);
    mMovimientos = new Vector<Movimiento>();
    mMarcaInternacional = marcainternacional;
    setmNombreEntidad(nombreentidad);
    setmCCV(ccv);
}

How can I have both constructors and dont ducplicate code?

3 Answers3

6

How can I have both constructors and dont ducplicate code?

A couple of ways:

  1. Have a private constructor they both chain to with the common parts, and then have each do its own thing after calling it. For example:

    private Credito(String numero, String titular, LocalDate fechacaducidad, int marcainternacional,
            String nombreentidad, int ccv) {
        mNumero = numero;
        mTitular = titular;
        mFechaDeCaducidad = fechacaducidad;
        mMovimientos = new Vector<Movimiento>();
        mMarcaInternacional = marcainternacional;
        setmNombreEntidad(nombreentidad); // *** See warning
        setmCCV(ccv);                     // *** See warning
    }
    
    public Credito(String numero, String titular, LocalDate fechacaducidad, double credito, int marcainternacional,
            String nombreentidad, int ccv) {
        this(numero, titular, fechacaducidad, marcainternacional, nombreentidad, ccv);
        mCredito = credito;
    }
    
    public Credito(String numero, String titular, LocalDate fechacaducidad, int tipo, int marcainternacional,
            String nombreentidad, int ccv) {
        this(numero, titular, fechacaducidad, marcainternacional, nombreentidad, ccv);
        mTipo = tipo;
        mCredito = calcularCredito(mTipo);
    }
    

    Re See warning - in general, it's problematic to call methods from constructors, for various reasons; see this question's answers for more.

  2. Use the builder pattern, which could well be useful anyway given how many parameters you have there. More in this answer and (less so) this question's answers.

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
1

The second constructor can simply become:

public Credito(String numero, String titular, LocalDate fechacaducidad, int tipo, int marcainternacional,
        String nombreentidad, int ccv) {
    this(numero, titular, fechacaducidad, calcularCredito(mTipo), marcainternacional, nombreentidad, ccv); 
}
rmlan
  • 4,387
  • 2
  • 21
  • 28
  • 1
    ...assuming calling `calcularCredito` with a completely un-initialized instance is okay, which...is not a safe assumption. It also encourages calling methods from the constructor, which [isn't generally a good idea](https://stackoverflow.com/questions/5230565/can-i-call-methods-in-constructor-in-java). – T.J. Crowder Apr 24 '18 at 17:53
  • I do not disagree. – rmlan Apr 24 '18 at 17:54
0

You can use something like this.

public Credito(String numero, String titular, LocalDate fechacaducidad, double credito, int marcainternacional,
        String nombreentidad, int ccv) {
    mCredito = credito;
    setmNombreEntidad(nombreentidad);
    commonFunction(numero, titular, fechacaducidad,  marcainternacional, nombreentidad, ccv);
}

public Credito(String numero, String titular, LocalDate fechacaducidad, int tipo, int marcainternacional,
        String nombreentidad, int ccv) {
    mTipo = tipo;
    mCredito = calcularCredito(mTipo);
    setmNombreEntidad(nombreentidad);
    commonFunction(numero, titular, fechacaducidad,  marcainternacional, nombreentidad, ccv);
}

private void commonFunction(String numero, String titular, LocalDate fechacaducidad,  int marcainternacional,
        String nombreentidad, int ccv) {
    mNumero = numero;
    mTitular = titular;
    mFechaDeCaducidad = fechacaducidad;
    mMovimientos = new Vector<Movimiento>();
    mMarcaInternacional = marcainternacional;
    setmCCV(ccv);
}
Naresh Bharadwaj
  • 192
  • 1
  • 12
  • ...assuming calling `calcularCredito` with an almost entirely un-initialized instance is okay, which...is not a safe assumption. It also encourages calling methods from the constructor, which [isn't generally a good idea](https://stackoverflow.com/questions/5230565/can-i-call-methods-in-constructor-in-java). – T.J. Crowder Apr 24 '18 at 17:53
  • It is depend on your case scenario. Sometimes you need to perform various kinds of business logic in constructor on the basis of certain arguments. In such cases, we can use private functions. – Naresh Bharadwaj Apr 24 '18 at 17:56