Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

152
Visualizações
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 Respostas
Responde à pergunta

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda