JavaRush /Blogue Java /Random-PT /Construtor padrão e preservação da integridade da classe ...
articles
Nível 15

Construtor padrão e preservação da integridade da classe em Java

Publicado no grupo Random-PT
Ao projetar classes destinadas à herança (por exemplo, classes abstratas), considera-se uma boa prática não implementar uma interface Serializable, e decidir individualmente em cada classe descendente se ela precisa ser serializada ou não. No entanto, tal classe deve ter um construtor padrão para que os mecanismos de serialização criem o objeto corretamente. E às vezes não há como fornecer um construtor padrão sem quebrar a integridade da classe. Construtor padrão e manutenção da integridade da classe em Java - 1Tal classe geralmente deve tomar como parâmetro algum objeto sem o qual não pode funcionar normalmente, e fornecer um construtor padrão violará a integridade da classe. Em tal situação, você pode fornecer um construtor, mas proibir trabalhar com ele até que seja totalmente inicializado. Para fazer isso, você pode introduzir um estado em uma classe e permitir que seus métodos sejam chamados apenas se o estado desta classe for “inicializado”. Exemplo do livro "Java Eficaz" :
public abstract class AbstractFoo {
    private int x, y;

    private enum State {
        NEW, INITIALIZING, INITIALIZED
    };

    private final AtomicReference<State> init = new AtomicReference<State>(State.NEW);

    protected AbstractFoo() {}

    public AbstractFoo(int x, int y) {
        initialize(x, y);
    }

    protected final void initialize(int x, int y) {
        if (!init.compareAndSet(State.NEW, State.INITIALIZING)) {
            throw new IllegalStateException("Already initialized");
        }
        this.x = x;
        this.y = y;
        init.set(State.INITIALIZED);
    }

    protected final int getX() {
        checkInit();
        return x;
    }

    protected final int getY() {
        checkInit();
        return y;
    }

    private void checkInit() {
        if (init.get() != State.INITIALIZED) {
            throw new IllegalStateException("Uninitialized");
        }
    }
}

class Foo extends AbstractFoo implements Serializable {
    private void readObject(ObjectInputStream s) throws IOException,
            ClassNotFoundException {
        s.defaultReadObject();
        int x = s.readInt();
        int y = s.readInt();
        initialize(x, y);
    }

    private void writeObject(ObjectOutputStream s) throws IOException {
        s.defaultWriteObject();
        s.writeInt(getX());
        s.writeInt(getY());
    }

    public Foo(int x, int y) {
        super(x, y);
    }
}
Ao mesmo tempo, todos os métodos desta classe devem verificar o estado atual da classe e evitar seu uso incorreto, e os métodos readObject()e devem ser definidos na classe descendente writeObject(). Link para a fonte original: http://0agr.ru
Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION