Java - Framework для определения, изменился ли объект / механизм обнаружения грязных

Уважаемые все, я в настоящее время реализую java-клиент, который довольно часто использует сторонние веб-сервисы. Для повышения производительности мне просто нравится вызывать веб-службы только в том случае, если объекты на моей стороне клиента были изменены (стали грязными).

Вместо того, чтобы писать собственный вид фреймворка, который может определять, является ли объект грязным, существует ли какая-либо открытая / общая структура, которая может быть повторно использована и не привязана к ее основному продукту (например, спящему режиму)?


person megloff    schedule 03.02.2016    source источник
comment
Вопросы, требующие от нас порекомендовать или найти книгу, инструмент, библиотеку программного обеспечения, учебное пособие или другой внешний ресурс, не относятся к теме Stack Overflow, поскольку они, как правило, привлекают самоуверенные ответы и спам. Вместо этого опишите проблему и то, что было сделано на данный момент для ее решения.   -  person Jim Garrison    schedule 03.02.2016
comment
Как сказал Джим. Но взгляните на ObservableValue или любую из Observable реализаций, исходящих от JavaFX. Уже в вашем JDK.   -  person Robin Jonsson    schedule 03.02.2016
comment
Спасибо вам обоим, я полностью согласен с Джимом, но я не люблю начинать с нуля, например. написание собственных методов установки, я ищу больше фреймворка или стратегии, которые можно использовать для простых java beans   -  person megloff    schedule 03.02.2016


Ответы (2)


Я предполагаю, что под объектом вы имеете в виду не одно скалярное значение, а компонент.

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

Другой вариант - сохранить копию старого экземпляра компонента и сравнить его. На самом деле проблема сводится к сравнению двух bean-компонентов, о чем здесь спрашивали: как в общем случае сравнить целые java beans? Возможно, вы найдете больше, существует множество фреймворков, имеющих дело с bean-компонентами в целом.

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

Уведомление об изменении. Я не рекомендую прикреплять слушателей изменений к каждому компоненту. Это может изменить вашу общую производительность и вызвать утечки памяти. Также существует проблема транзакции: если обновляется более одного свойства bean-компонента, когда завершается обновление bean-компонента? Так что вам в любом случае нужен явный вызов после мутации.

Примечание для меня и других специалистов, занимающихся кешированием: На самом деле это вариант использования для предоставления такого метода, как Cache.putIfNotEquals (key, value), в кеше, что не требует больших усилий. В кеше уже хранится предыдущее значение, и он вызывает средство записи кеша (при настройке через запись) только в том случае, если значение изменилось.

person cruftex    schedule 03.02.2016
comment
Большое тебе спасибо! Да, я пришел к такому же выводу после некоторых исследований в Google, которые вы используете - собственные методы Setter - или улучшение байтового кода - или, как вы указали, сериализацию. Поэтому я решил пойти на сериализацию - person megloff; 03.02.2016

Чтобы дать другим отправную точку, как это может выглядеть.

    TestBean bean1 = new TestBean("AAA");
    TestBean bean2 = new TestBean("BBB");

    log.info("serialize...");
    ByteArrayOutputStream str1 = new ByteArrayOutputStream();
    ObjectOutputStream oos1 = new ObjectOutputStream(str1);
    oos1.writeObject(bean1);
    byte[] serialized1 = str1.toByteArray();
    oos1.close();

    ByteArrayOutputStream str2 = new ByteArrayOutputStream();
    ObjectOutputStream oos2 = new ObjectOutputStream(str2);
    oos2.writeObject(bean2);
    byte[] serialized2 = str2.toByteArray();
    oos2.close();

    log.info("compare");
    boolean same = Arrays.equals(serialized1, serialized2);

Преимущество такого подхода

  • вы сериализуете всю структуру объекта, поэтому он поддерживает сложные иерархии из коробки, и вам не нужно заботиться о циклах (родительские / дочерние)
  • вы можете использовать "временное" ключевое слово для членов, которые вы хотите исключить из сериализации / сравнения
  • вам не нужно добавлять какой-то шаблонный код в классы bean-компонентов (кроме того, что класс должен реализовывать интерфейс Serializable)

недостатки

  • он не мелкозернистый, поэтому вы не получите из коробки, какие поля грязные. Существуют сложные подходы с использованием собственный формат сериализации
  • У меня еще не было мысли о производительности, но я мог представить, что другие подходы также предоставляются не бесплатно, поэтому здесь вам нужно протестировать и настроить подход самостоятельно.
person megloff    schedule 03.02.2016