Некоторые Вопросы относительно Неизменного образца - PullRequest
0 голосов
/ 03 декабря 2018

У меня есть несколько вопросов относительно неизменного паттерна.Прежде всего, чтобы решить проблему, нам необходимо убедиться в следующем:

1) Методы экземпляра, которые обращаются к свойствам, не должны изменять переменные экземпляра.

2) Убедитесь, что конструктор неизменяемого классаединственное место, где установлены значения переменных экземпляра или изменено .Я думаю, что, сделав переменные inctance в качестве окончательных переменных, тогда, если существует метод, который изменяет эту переменную, произойдет сбой, даже конструктор не сможет изменить эту переменную, так почему мы должны учитывать эти два утверждения, если мыможно использовать последнее ключевое слово ??Я знаю, что мне чего-то не хватает.

Ответы [ 2 ]

0 голосов
/ 03 декабря 2018

Прежде всего шаблоны проектирования не ограничиваются Java.Они могут быть реализованы на разных языках, имеющих разный вкус.Не у всех языков есть финал, даже у java не было финалов с самого начала.

Но, учитывая строгий случай java, финал не гарантирует неизменность:

  • в объектесостояние может быть изменено с использованием методов членов, если они доступны.
  • final, примененный к объекту, гарантирует, что переменная указывает на тот же объект, но не накладывает никаких ограничений во избежание изменения состояния (ball.setColor («красный») может быть выполнен на последнем шаре)
  • неизменность означает, что переменная должна быть переназначена другим объектом

Например:

Ball ball = new Ball(); 
ball = ball.makeRed();

В этом случае шар - это еще один объект мяча (сделайте так, чтобы шар клонировал шар и изменил цвет).То же самое происходит, когда мы запускаем метод для объекта String, создается новый объект строки для отражения изменений и возвращается:

String ball = 'Blue Ball';
ball = ball.replace('Blue', 'Red');
0 голосов
/ 03 декабря 2018

Есть одна важная вещь для создания настоящих неизменных.Возможно, компоненты являются изменяемыми структурами данных, такими как java.util.Date.Возьмите этот простой класс для демонстрационных целей:

final class DateWrapper {
  private final Date date;
  public DateWrapper(Date date) {
    this.date = date;
  }
  public Date getDate() {
    return date;
  }
}

Теперь вы можете написать этот код:

DateWrapper dw = new DateWrapper(new Date());
dw.getDate().setYear(2020);

Это изменяет переменную экземпляра date объекта dw класса DateWrapper.Так что этот класс не является действительно неизменным.

Чтобы решить эту проблему, вы должны сделать защитные копии, например:

final class DateWrapper {
  private final Date date;
  public DateWrapper(Date date) {
    // It must not be possible to modify the date after construction.
    // So use a copy of the original object in class DateWrapper.
    this.date = new Date(date.getTime());
  }
  public Date getDate() {
    // It must not be possible to modify the date in DateWarapper
    // So return a copy.
    return new Date(date.getTime());
  }
}

Так что ни один другой класс не получит изменяемую ссылку на внутренние элементы DateWrapper.

Еще одно правило: сделать ваш класс окончательным, иначе подкласс может вести себя как класс immutabele, нарушая контракт неизменности.Это пример вредоносного подкласса, который работает, только если DateWrapper не является окончательным:

class Date2Wrapper extends DateWrapper {
  final Date date2;
  public Date2Wrapper(Date date) {
    super(date);
    this.date2 = date;
  }
  public Date getDate() {
    return date2;
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...