У меня есть сериализуемый объект с зарегистрированными слушателями. В настоящее время список слушателей хранится в объекте как transient. Когда объект сериализуется, а затем десериализуется, очевидно, что слушатели больше не регистрируются.
Каким будет самый безопасный и лучший способ автоматически перерегистрировать слушателей после десериализации объекта? Есть ли здесь хороший шаблон дизайна?
Вау ... Я думаю, вам понадобится много информации ... Если объект сериализуется для (предположительно) перемещения через границы приложения, ссылки будут недействительными, не так ли?




Вы можете использовать прокси-объект, который действует и как слушатель, и как передатчик событий, и назначить ему реальных слушателей, а затем назначить его как слушателя сериализуемого объекта. Когда вы сериализуете его, а затем десериализуете, просто переназначьте его как слушателя десериализованного объекта.
Я бы построил независимую структуру событий, что означает, что производитель событий не будет напрямую привязан к потребителю событий. Он может состоять из EventManager, EventProducer и EventListener, работающих вместе с семантикой публикации / подписки.
public interface EventManager {
public void postEvent(Event event);
public void addListener(Class eventType, EventListener listener);
}
public interface EventListener {
public void handleEvent(Event event);
}
Таким образом, когда вы сериализуете производителя, EventManager по-прежнему поддерживает список подписанных слушателей. когда объект десериализован, он все еще может отправлять события в EventManager.
В общем, я не нашел для этого никакого полезного шаблона. Но сочетание нескольких будет нормально :). Вопрос в том, как вы справляетесь с десериализацией? При использовании стандартного способа вы можете ввести механизм поиска, который будет использоваться для поиска локальных слушателей и повторной привязки их к только что десериализованному экземпляру. Если у вас есть собственный десериализатор, путь будет проще. Просто десериализуйте объект и зарегистрируйте локальных слушателей. Десериализатор может выступать в качестве прослушивателя прокси, если это возможно. Как сказал Панайотис, введение некоторой несвязанной модели также должно быть полезным. Точное решение зависит от вашей реальной потребности, но не забудьте его ЦЕЛОВАТЬ.
Используйте реестр, в котором зарегистрированы и ваш издатель, и подписчики. Как было опубликовано Корросом, в стране OSGI это называется шаблоном доски.
Если вы реализуете readObject (), вы можете реконструировать переходное состояние как часть десериализации. Вы должны рассматривать десериализацию как построение объекта (потому что это так).
private void readObject(ObjectInputStream in)
throws ClassNotFoundException, IOException {
// do normal serialization first!
in.defaultReadObject();
// put code here that can somehow reconstruct your listeners
// presumably you have someplace you can look them up
}
Это немного расплывчато ... возможно, вы захотите дать более подробную информацию ... каковы обстоятельства, при которых он сериализуется / десериализуется ...