リスナーが登録されたシリアライズ可能なオブジェクトがあります。現在、リスナーのリストは としてオブジェクトに格納されていますtransient
。オブジェクトがシリアル化されてから逆シリアル化されると、明らかにリスナーは登録されなくなります。
オブジェクトが逆シリアル化されたら、リスナーを自動的に再登録するための最も安全で最良の方法は何でしょうか? ここで役立つ良いデザインパターンはありますか?
リスナーが登録されたシリアライズ可能なオブジェクトがあります。現在、リスナーのリストは としてオブジェクトに格納されていますtransient
。オブジェクトがシリアル化されてから逆シリアル化されると、明らかにリスナーは登録されなくなります。
オブジェクトが逆シリアル化されたら、リスナーを自動的に再登録するための最も安全で最良の方法は何でしょうか? ここで役立つ良いデザインパターンはありますか?
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
}
イベントのリスナーとブロードキャスターの両方として機能するプロキシ オブジェクトを使用し、実際のリスナーをそれに割り当ててから、シリアライズされるオブジェクトのリスナーとして割り当てることができます。シリアル化してから逆シリアル化する場合は、逆シリアル化されたオブジェクトのリスナーとして再割り当てするだけです。
私は分離されたイベント フレームワークを構築します。つまり、イベント プロデューサーはイベント コンシューマーに直接バインドされません。これは、パブリッシュ/サブスクライブ セマンティクスと連携して動作する EventManager、EventProducer、および EventListener で構成できます。
パブリック インターフェイス EventManager { public void postEvent(イベント イベント); public void addListener(Class eventType, EventListener リスナー); } パブリック インターフェイス EventListener { public void handleEvent(イベント イベント); }
このように、プロデューサーをシリアル化すると、EventManager はサブスクライブされたリスナーのリストを維持します。オブジェクトがデシリアライズされても、イベントを EventManager にポストできます。
パブリッシャーとサブスクライバーの両方が登録するレジストリーを使用します。Korrosによって投稿されたように、OSGIランドではホワイトボードパターンと呼ばれます。
一般に、これに役立つパターンは認識されませんでした。しかし、いくつかの組み合わせはOKです:)。問題は、デシリアライゼーションをどのように処理するかです。標準的な方法を使用する場合は、ローカル リスナーを見つけて、それらを新たに逆シリアル化されたインスタンスに再バインドするために使用されるルックアップ メカニズムを導入できます。独自のデシリアライザーがある場合、方法はより簡単になります。オブジェクトを逆シリアル化し、ローカル リスナーを登録するだけです。可能であれば、デシリアライザーはプロキシ リスナーとして機能できます。パナギオティスが言ったように、いくつかの分離モデルを導入することも役立つはずです. 正確な解決策は、実際のニーズによって異なりますが、 KISSすることを忘れないでください。