Фактический случай:
я хотел бы переопределить public boolean equals(java.lang.Object obj)
для некоторых объектов в моем текущем проекте Java. Этот метод по-прежнему должен возвращать true
, когда объект вызова считается равным текущему. Однако при установлении равенства между объектами мне необходимо сохранить некоторые результаты обработки в структуре данных, принадлежащей другому, синглтону, классу (я должен сохранить список различий, если они есть, для дальнейшего использования в рабочем процессе приложения).
Вызов переопределенного equals()
будет иметь побочный эффект, тесно связанный с тем, как я устанавливаю равенство объектов. Однако у метода нет побочных эффектов, если он не переопределен. Это считается недостатком конструкции? Есть ли хорошая практика, противоречащая такому подходу?
Документация Oracle о переопределении методов довольно лаконична, имхо, по этому поводу: «Способность подкласса переопределять метод позволяет классу наследоваться от суперкласса, поведение которого «достаточно близко», а затем модифицировать поведение по мере необходимости.».
Я не вижу никаких ограничений в таком заявлении, но я хотел бы получить совет от разработчиков/дизайнеров/архитекторов ООП.
Спасибо!
Подробнее (упрощенный код):
// Dataform is a JAX bean class
public class Dataform {
String name;
// Column is a JAX bean class
ArrayList<Column> columns;
// Footer is a JAX bean class
Footer footer;
// equals is redefined the same way for each JAX bean classes
@Override
public boolean equals(Object obj){
if(this.getClass().isInstance( obj )){
// equalsXML is a method that compares XML elements (JAX beans in this case). This method can in turn call equals() on
if (XMLObject.equalsXML( this, obj ).isEmpty()){
// Store differences in singleton class for future access
return false;
}
else{
return true;
}
}
else{
return super.equals( obj );
}
}
}
equals()
или из другого места. - person Andreas   schedule 24.02.2016equals
последовательно возвращает результат при вызове, и вы не изменяете сравниваемые объекты, побочных эффектов нет. - person OneCricketeer   schedule 24.02.2016.equals()
и бизнес-логика хранения и обработки этих различий так далеки друг от друга... Вы уверены, что вам действительно нужно делать это при каждом вызове.equals()
? Вы уверены, что кто-то из ваших коллег (или вы сами) не будет использовать.equals()
в каком-то месте, где вам не нужно обрабатывать эти различия, а потом не будет тратить часы на отладку, пытаясь понять, что пошло не так в продакшене? . Либо храните разницу явно в тех местах, где вы хотите это сделать, либо будьте рискованным парнем и используйте АОП. - person Yaroslav Admin   schedule 24.02.2016equals()
для этих компонентов JAX будет вызываться только один раз с определенным аргументом, как это предусмотрено в рабочем процессе приложения. После этого информация о равенстве сохраняется в структуре данных, доступной для всего приложения без необходимости повторной проверки объектов (база, вызов). Оценка того, равны ли два объекта Dataform, является дорогостоящим, я хотел сохранить эту информацию (а также различия, если они есть) только один раз. Я также добавлю защиту, которая предотвратит повторную обработку, если структура данных для текущего объекта уже была обновлена. - person A. Karali   schedule 24.02.2016equals
метод простоreturn getClass().isInstance(obj)? !XMLObject.equalsXML(this, obj).isEmpty(): super.equals(obj);
- person Holger   schedule 19.10.2016