Неизменяемый интерфейс

В объектно-ориентированном программировании « неизменяемый интерфейс » — это шаблон для проектирования неизменяемого объекта . [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             

Ссылаясь только на неизменяемый интерфейс, нельзя вызывать метод, который изменяет состояние конкретного объекта.

Преимущества

  • Ясно передает неизменное намерение типа.
  • В отличие от типов, реализующих шаблон Immutable Wrapper, не требуется «отменять» изменяющиеся методы, выдавая инструкцию « No Operation » или выдавая исключение времени выполнения при вызове изменяющегося метода.

Недостатки

  • Для экземпляров, на которые ссылается неизменяемый тип интерфейса, возможно приведение к их конкретному, изменяемому типу и изменение их состояния. Например:
    public void mutate ( ImmutablePoint2D point ) { (( Point2D ) point ). setX ( 42 ); // этот вызов допустим, поскольку тип был // преобразован в изменяемый класс Point2D }       
  • Конкретные классы должны явно декларировать, что они реализуют неизменяемый интерфейс. Это может быть невозможно, если конкретный класс «принадлежит» стороннему коду, например, если он содержится в библиотеке.
  • Объект на самом деле не является неизменяемым и, следовательно, не подходит для использования в структурах данных, полагающихся на неизменяемость, таких как хэш-карты. И объект может быть изменен одновременно с "изменяемой стороны".
  • Некоторые оптимизации компилятора, доступные для неизменяемых объектов, могут быть недоступны для изменяемых объектов.

Альтернативы

Альтернативой шаблону неизменяемого интерфейса является шаблон неизменяемой оболочки.

Постоянные структуры данных фактически неизменяемы, но допускают возможность изменения своих представлений.

Ссылки

  1. ^ Неизменяемый интерфейс, c2.com
    - immutable, mindprod.com
    - Питер Хаггар, "Практическая практика Java 65: использование наследования или делегирования для определения неизменяемых классов", informIT , 22 января 2001 г.
Retrieved from "https://en.wikipedia.org/w/index.php?title=Immutable_interface&oldid=1192996297"