Immutable interface

From Wikipedia, the free encyclopedia
Jump to: navigation, search

In object-oriented programming, "Immutable Interface" is a pattern for designing an immutable object.[1][2][3] The immutable interface pattern involves defining a type which does not provide any methods which mutate state. Objects which are referenced by that type are not seen to have any mutable state, and appear immutable.

Example[edit]

Java[edit]

Consider a Java class which represents a two-dimensional point.

public class Point2D {
    private int x;
    private int y;
    public Point2D(int x, int y) { this.x = x; this.y = y; }
 
    public int getX() { return this.x; }
    public int getY() { return this.y; }
 
    public void setX(int newX) { this.x = newX; }
    public void setY(int newY) { this.y = newY; }
}

The class Point2D is mutable: its state can be changed after construction, by invoking either of the setter methods (setX() or setY()).

An immutable interface for Point2D could be defined as:

public interface ImmutablePoint2D {
    public int getX();
    public int getY();
}

By making Point2D implement ImmutablePoint2D, client code could now reference a type which does not have mutating methods, and thus appears immutable. This is demonstrated in the following example:

ImmutablePoint2D point = new Point2D(0,0);  // a concrete instance of Point2D is referenced by the immutable interface
int x = point.getX(); // valid method call
point.setX(42); // compile error: the method setX() does not exist on type ImmutablePoint2D

By referencing only the immutable interface, it is not valid to call a method which mutates the state of the concrete object.

Advantages[edit]

  • Clearly communicates the immutable intent of the type.
  • Unlike types implementing the Immutable Wrapper pattern, does not need to 'cancel out' mutating methods by issuing a "No Operation" instruction, or throwing a runtime exception when a mutating method is invoked.

Disadvantages[edit]

  • It is possible for instances referenced by the immutable interface type to be cast to their concrete, mutable type, and have their state mutated. For example:
public void mutate(ImmutablePoint2D point) {
    ((Point2D)point).setX(42); // this call is legal, since the type has
                               // been converted to the mutable Point2D class
}
  • Concrete classes have to explicitly declare they implement the immutable interface. This may not be possible if the concrete class "belongs to" third-party code, for instance, if it is contained within a library.

Alternatives[edit]

An alternative the immutable interface pattern is the Immutable Wrapper pattern.

References[edit]