Как бороться с различными случаями защитного программирования?

StackOverflow https://stackoverflow.com//questions/21014651

Вопрос

Это пример защитного копирования в Effective java.Предположим, что сценарий в моих базовых вопросах нуждается в защитной копии и не может обойтись без комментария, в котором клиент просит избежать изменения передаваемых объектов.

public Period(Date start, Date end) {
    this.start = new Date(start.getTime());
    this.end = new Date(end.getTime());
}

Вопросы:

  1. Что делать, если Date у меня не было конструктора, чтобы принять себя, чтобы сделать мое "я" более общим, объект передается без механизма самовоспроизведения, и такой объект нам не принадлежит, т.е. мы не можем изменить его каким-либо образом?

  2. Что, если конструктор принял параметр типа в качестве аргумента, скажем Period(T object) и T может быть изменяемым, поэтому нуждается в защитной копии.Мы не имеем ни малейшего представления о том, что такое T.Как сделать защитную копию в этом случае?

  3. Что такое интерфейс, передается там, где некоторые из его подклассов действительно имеют конструктор типа Date чтобы создать объект сам по себе, а некоторые из его подклассов не имеют для этого никакого механизма?

  4. Насколько глубоко мы должны копировать в целях защиты?Допустим, мы скопировали массив, но элементы массива были изменяемыми?

Это было полезно?

Решение

  1. Если доступно все его состояние, вы можете извлечь его состояние и самостоятельно создать новый объект.В противном случае вы ничего не сможете с этим поделать, кроме как использовать неприятные приемы отражения или сериализации.
  2. Если T не является экземпляром класса, который позволяет копировать сам себя, вы ничего не сможете сделать.
  3. Ты ничего не можешь с этим поделать.
  4. Это зависит.

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

Вы вынуждены создать защитную копию Date, потому что это изменяемый тип значения, который не должен быть изменяемым и не был бы им, если бы он был правильно спроектирован.Если вы поддерживаете неизменяемость типов значений, то защитные копии становятся ненужными.Для типов, не содержащих значений, обычно требуется не копия, а ссылка на объект.

Другие советы

  1. Если вы все равно не можете изменить состояние объекта, вам не нужна защитная копия.
  2. Единственное, что вы можете сделать, это предположить вероятную реализацию T и проверить их с помощью Экземпляр.
  3. То же, что и 2.
  4. На ваше усмотрение.Если вы предполагаете, что модификация элементов массива может нарушить работу вашей программы в других местах, вам также следует скопировать их все.

Защитное программирование имеет значение, когда объекты, которые вы передаете методу, изменяемы.Хорошей практикой (также описанной в книге "Эффективная Java") является то, чтобы сделать их неизменяемыми.

  1. Если класс Date не является окончательным, вы можете написать для него класс-оболочку, который является подклассом Date.
  2. Это зависит.Вероятно, в его клонировании не будет необходимости.
  3. Это не должно тебя беспокоить.Разработчик интерфейса должен позаботиться о проблемах синхронизации.Как правило, хорошей практикой является передача интерфейсов вместо их реализаций.
  4. Для стандартных коллекций java в java.util есть множество служебных методов.Класс Collections, такой как unmodifiableList и unmodifiableMap, предназначен для использования в защитном программировании.
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top