场景
我将尽可能简洁。基本上参考此classdiag,我有一个外观管理一个列表SocketManager (管理一个Socket连接)。每个 SocketManager 使用唯一的SocketUserId登录到远程服务器。此外,每个 SocketManager 将接受来自客户端的消息,这些消息发往特定的收件人列表。为了便于讨论,请将这些收件人视为由名称标识的远程数据桶。
客户将发送如下数据:
SocketFacade facade = ...;
byte[] data = ...
facade.sendData( receipient, data );
当SocketFacade启动时,它将查询一个mysql表,该表返回SocketUserId和Receipients之间的1-m关系。我将使用MultiValuedMap表示这种1-m关系。然后,将通过遍历地图来启动多个 SocketManager 。
(1) Map< SocketUserId, List<Receipient> >
例如假设我们有2个 SocketManager ,分别带有SocketUserIds“alice”和“tom”
+----SocketManager1 ( "alice" ) for Receipients { "B", "C" }
|
SocketFacade
|
+----SocketManager2 ( "tom" ) for Receipients { "A", "D" }
问题
关于如何实现sendData方法,我处于困境。基本上,我需要一种从收件人(例如“B”)映射到其负责的 SocketManager (例如SocketManager1)的方法。
假设我这样做
(2) Map< SocketUserId, SocketManager >
(3) Map< Receipient, SocketUserId >
interface Callback
{
void receipientAdded( Receipient r );
void receipientDeleted( Receipient r );
}
最佳答案
在每个SocketManager
中保留对Receipient
的引用。这样,您可以避免映射(它需要更多的RAM,速度较慢,并且不添加任何值)。
在SocketManager
中,保留Receipient
的列表。添加和删除Receipient
时,更新指向SocketManager
的指针。
在SocketFacade
中,您需要一个映射,该映射接受SocketUserId
并返回SocketManager
。该地图是通过查询地图中的ID来填充的。所有经理都存在后,将收件人添加到每个中。这需要两个SQL查询。
使用任何ORM工具都很容易映射。