mardi 29 août 2017

How to enforce implementing classes to be immutable?

While designing a small app, I've found that it would be very convenient for implementations of an interface A to be immutable.

I can't just use the immutable interface pattern because the interface has a method execute(Command command), which has a big potential to mutate state. I expect implementations of A to have fields of mutable types. The given Command will operate on them, for instance:

public class AImpl implements A {

    private List<PotentiallyMutable> elements;

    @Override
    public void execute(Command command) {
        elements.get(command.getUnitIndex()).doSomething(); // State changed
    }
}

But as I said I want instances to be immutable. I can specify that implementations should be immutable in the javadoc. I can also change the method signature to A execute(Command) as a reminder to implementors, and suggesting implementations to be used à la BigDecimal/String:

aImpl = aImpl.execute(command)

Which is an idiom I don't like. Also, it obviously wouldn't prevent this:

    @Override
    public A execute(Command command) {
        elements.get(command.getIndex()).doSomething(); // State changed
        return this;
    }

Is there anything else that I can do or any other pattern that I can apply?

Aucun commentaire:

Enregistrer un commentaire