DEV Community

Java Efetivo (livro)
Java Efetivo (livro)

Posted on

Item 76: Empenhe-se para obter a atomicidade de falha

Definição

  • Um objeto deve permanecer em um estado utilizável e bem definido mesmo após lançar uma exceção durante uma operação.
  • Métodos que garantem que o objeto não será alterado após uma falha possuem atomicidade de falha.

Métodos para obter atomicidade de falha

Objetos Imutáveis

  • A atomicidade é inerente a objetos imutáveis porque seu estado não pode ser alterado após a criação.

Exemplo:

// Exemplo simplificado de um objeto imutável
public final class ImmutableObject {
    private final int value;

    public ImmutableObject(int value) {
        this.value = value;
    }

    public int getValue() {
        return value;
    }
}

Enter fullscreen mode Exit fullscreen mode

Validação de Parâmetros Antes da Operação

  • Verificar a validade dos parâmetros antes de modificar o objeto.

Exemplo:

// Verificação de estado em um método Stack.pop()
public Object pop() {
    if (size == 0) {
        throw new IllegalStateException("Stack is empty");
    }
    Object result = elements[--size];
    elements[size] = null; // Evitar vazamento de memória
    return result;
}

Enter fullscreen mode Exit fullscreen mode

Ordenação de Operações

  • Garantir que partes passíveis de falha ocorram antes de alterar o estado do objeto.

Exemplo:

// Adicionando elemento em TreeMap (simulação)
public void addElement(TreeMap<String, Integer> map, String key, Integer value) {
    if (key == null || value == null) {
        throw new IllegalArgumentException("Key or value is null");
    }
    map.put(key, value); // Falhas na comparação ocorrem antes de alterar a estrutura
}

Enter fullscreen mode Exit fullscreen mode

Cópias Temporárias

  • Realizar operações em uma cópia temporária do objeto e substituir o original somente se a operação for bem-sucedida.

Exemplo:

// Simulação de operação em cópia temporária
public void sortList(List<Integer> list) {
    List<Integer> temp = new ArrayList<>(list);
    try {
        Collections.sort(temp);
        list.clear();
        list.addAll(temp);
    } catch (Exception e) {
        // A lista original permanece intacta
    }
}

Enter fullscreen mode Exit fullscreen mode

Código de Recuperação

  • Reverter o estado de um objeto ao original em caso de falha.
  • Geralmente usado em estruturas de dados persistentes.

Exemplo:

public void updateRecord(Database db, Record record) {
    Record backup = db.getRecord(record.getId()); // Fazer backup
    try {
        db.update(record);
    } catch (Exception e) {
        db.update(backup); // Reverter em caso de falha
    }
}

Enter fullscreen mode Exit fullscreen mode

Exceções Notáveis

  • Erros irreparáveis como ConcurrentModificationException ou AssertionError:
  • A atomicidade de falha não é garantida e nem necessária.

Custo e Complexidade

  • Nem sempre é prático implementar a atomicidade de falha, especialmente em operações complexas ou de alto custo.

Boa Prática

  • Métodos devem documentar o estado do objeto após uma falha se não garantirem atomicidade.

Resumo Final

  • Recomendação: Toda exceção que faça parte da especificação de um método deve deixar o objeto no mesmo estado anterior à invocação.
  • Exceções: Quando isso não for possível ou prático, a documentação da API deve ser clara sobre os impactos no estado do objeto.

Image description

Postmark Image

Speedy emails, satisfied customers

Are delayed transactional emails costing you user satisfaction? Postmark delivers your emails almost instantly, keeping your customers happy and connected.

Sign up

Top comments (0)

Hostinger image

Get n8n VPS hosting 3x cheaper than a cloud solution

Get fast, easy, secure n8n VPS hosting from $4.99/mo at Hostinger. Automate any workflow using a pre-installed n8n application and no-code customization.

Start now

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay