Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

149
Vistas
Changing an immutable class in legacy code

I want to replace the (mutable) class

class OldValue {
  private int value;
  
  public OldValue(int value) { this.value = value; }
  
  public int getValue() { return value; }
  
  public void setValue(int value) { this.value = value; }
}

with the immutable class

class NewValue {
  private final int value;
  
  public NewValue(int value) { this.value = value; }
  
  public int getValue() { return value; }
  
  /* no setter, obviously */
}

In most parts of the code something like newValue.set(777) can be replaced by newValue = new NewValue(777). However, there are some legacy parts of the code with something like

class ManagementServiceProviderFacadeSingletonAbstractFactoryObserver {

  public void setTheValue(OldValue oldValue) {
    oldValue.setValue(555);
  }

}

class Data {
  private OldValue oldValue;
  
  public OldValue get() { return oldValue; }
}


class SomewhereElse {

  public void frobnicate(Data data, ManagementServiceProviderFacadeSingletonAbstractFactoryObserver x) {
    x.setTheValue(data.get());
  }
}

These legacy parts are very hard to change and we would like to adapt it as little as possible. Is there a way to write some kind of "evil" setter method that could be used in the legacy code? Something like

class EvilSetter {

  public static void evilSet(NewValue newValue, int x) {
    // temporarily make newValue.value both public and non-final, set it to x
  }
}

Is there some other way without losing the immutability and elegance of the new design?

over 4 years ago · Santiago Trujillo
1 Respuestas
Responde la pregunta

0

I'd probably keep both types, leave the legacy code using the old type alone and provide adapter methods for converting between the two.

public class LegacyValueAdapter {

    public static OldValue toOldValue(NewValue newValue) {
        return new OldValue(newValue.getValue);
    }

    public static NewValue toNewValue (OldValue oldValue) {
        return new NewValue(oldValue.getValue);
    }

}

Clearly document that these should only be used for interfacing with the legacy code, mark as deprecated as needed. This clearly isn't ideal, but that applies to the entire situation.

If the class is more complicated (e.g. also has methods with some non-trivial behavior), it might be worth implementing OldValue by wrapping an instance of NewValue, but in this simple case that won't provide much benefit.


I strongly advise against any reflection-hacks, as they would invalidate most the benefits of using the immutable types in the first place. Don't give me a type that looks immutable, but then sneakily change the value somehow - that breaks expectations of users and hides the risks for race-conditions.

over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda