В объектно-ориентированном программировании « неизменяемый интерфейс » — это шаблон для проектирования неизменяемого объекта . [1] Шаблон неизменяемого интерфейса подразумевает определение типа, который не предоставляет никаких методов, изменяющих состояние. Объекты, на которые ссылается этот тип, не рассматриваются как имеющие какое-либо изменяемое состояние и кажутся неизменяемыми.
Рассмотрим класс Java, представляющий двумерную точку.
public class Point2D { private int x ; private int y ; public Point2D ( int x , int y ) { this.x = x ; this.y = y ; } public int getX ( ) { вернуть это.x ; } public int getY ( ) { вернуть это.y ; } public void setX ( int newX ) { this.x = newX ; } public void setY ( int newY ) { this.y = newY ; } }
Класс Point2D является изменяемым: его состояние можно изменить после создания, вызвав любой из методов-сеттеров ( setX()
или setY()
).
Неизменяемый интерфейс для Point2D можно определить следующим образом:
открытый интерфейс ImmutablePoint2D { public int getX (); public int getY (); }
Заставив Point2D реализовать ImmutablePoint2D, клиентский код теперь может ссылаться на тип, который не имеет методов мутации, и, таким образом, выглядит неизменяемым. Это показано в следующем примере:
ImmutablePoint2D point = new Point2D ( 0 , 0 ); // на конкретный экземпляр Point2D ссылается неизменяемый интерфейс int x = point . getX (); // допустимый вызов метода int y = point . setX ( 42 ); // ошибка компиляции: метод setX() не существует для типа ImmutablePoint2D
Ссылаясь только на неизменяемый интерфейс, нельзя вызывать метод, который изменяет состояние конкретного объекта.
public void mutate ( ImmutablePoint2D point ) { (( Point2D ) point ). setX ( 42 ); // этот вызов допустим, поскольку тип был // преобразован в изменяемый класс Point2D }
Альтернативой шаблону неизменяемого интерфейса является шаблон неизменяемой оболочки.
Постоянные структуры данных фактически неизменяемы, но допускают возможность изменения своих представлений.