Я хочу предупредить разработчика, когда он попытается изменить неизменяемый объект. Неизменяемый объект на самом деле является расширением изменяемого объекта и переопределяет сеттеры указанного объекта, чтобы сделать его неизменяемым.
Изменяемый базовый класс: Vector3
public class Vector3 {
public static final Vector3 Zero = new ImmutableVector3(0, 0, 0);
private float x;
private float y;
private float z;
public Vector3(float x, float y, float z) {
this.x = x;
this.y = y;
this.z = z;
}
public void set(float x, float y, float z) {
this.x = x;
this.y = y;
this.z = z;
}
}
Неизменяемая версия: ImmutableVector3
public final class ImmutableVector3 extends Vector3 {
public ImmutableVector3(float x, float y, float z) {
super(x, y, z);
}
//Made immutable by overriding any set functionality.
@Override
public void set(float x, float y, float z) {
throw new Exception("Immutable object."); //Should I even throw an exception?
}
}
Мой вариант использования выглядит следующим образом:
public class MyObject {
//position is set to a flyweight instance of a zero filled vector.
//Since this is shared and static, I don't want it mutable.
private Vector3 position = Vector3.Zero;
}
Допустим, разработчик в моей команде решил, что ему нужно манипулировать положением объекта, но в настоящее время он установлен на статический неизменяемый экземпляр общего вектора Vector3.Zero.
Было бы лучше, если бы он знал заранее, что ему нужно создать новый экземпляр изменяемого вектора, если вектор положения установлен на общий экземпляр Vector3.Zero:
if (position == Vector3.Zero)
position = new Vector3(x, y, z);
Но, скажем, он не проверяет это первым. Я думаю, в этом случае было бы хорошо выбросить Exception, как показано выше, в методе ImmutableVector3.set(x,y,z)
. Я хотел использовать стандартное исключение Java, но не был уверен, какое из них будет наиболее подходящим, и я не на 100% уверен, что это лучший способ справиться с этим.
Предложения, которые я видел (этот вопрос) [Подходит ли IllegalStateException для неизменяемого объекта? кажется, предлагает следующее:
- IllegalStateException - но это неизменяемый объект, поэтому имеет только одно состояние
- UnsupportedOperationException — метод
set()
не поддерживается, поскольку он переопределяет базовый класс, так что это может быть хорошим выбором. - NoSuchElementException - я не уверен, что это был бы хороший выбор, если бы метод не считался
element
.
Кроме того, я даже не уверен, что должен создавать здесь исключение. Я мог бы просто не менять объект и не предупреждать разработчика, что он пытается изменить неизменяемый объект, но это тоже кажется хлопотным. Проблема с созданием исключения в ImmutableVector3.set(x,y,z)
заключается в том, что set
должно вызывать исключение как для ImmutableVector3
, так и для Vector3
. Так что теперь, хотя Vector3.set(x,y,z)
никогда не вызовет исключение, его нужно поместить в блок try/catch
.
- Я упускаю из виду другой вариант, кроме создания исключений?
- Если исключения — лучший способ, какое исключение выбрать?
UnsuppoertedOperationException
.unmodifiable*
декораторы изCollection
— хороший прецедент. - person kiheru   schedule 29.08.2013