算法如何选择合适的java数据结构来建模1n关系映射?
场景
我将尽可能简洁。基本上,关于这个classdiag,我有一个facade,它管理一个SocketManager列表(它管理一个socket连接)。每个SocketManager都使用唯一的SocketUserId登录到远程服务器。此外,每个SocketManager将接受来自特定接收者列表的客户端的消息。为便于讨论,请考虑这些“强>收件人< /St>”,简单地称为名称标识的远程数据桶。
客户端将发送如下数据: 当SocketFacade启动时,它将查询一个mysql表,该表返回SocketUserId和receipents之间的1-m关系。我将使用MultiValuedMap来表示这个1-m关系。然后,通过迭代映射启动多个SocketManager 例如,假设我们有2个SocketManagers,其中SocketUserIds“alice”&;分别是“汤姆” 问题 对于如何实现sendData方法,我感到困惑。基本上,我需要一种从接收者(例如“B”)映射到其负责的SocketManager(例如SocketManager 1)的方法 让我们假设我这样做 SocketFacade还支持改变(1)表示的关系的方法。如果我写入数据库,则(1)、(2)和中的内存数据结构;(3) 将需要同步更改SocketFacade也必须是线程安全的。最初的想法是使用某种发布-订阅系统,通过这种系统,对数据库的添加/删除将导致更改通过回调传播SocketFacade facade = ...;
byte[] data = ...
facade.sendData( receipient, data );
(1) Map< SocketUserId, List<Receipient> >
+----SocketManager1 ( "alice" ) for Receipients { "B", "C" }
|
SocketFacade
|
+----SocketManager2 ( "tom" ) for Receipients { "A", "D" }
(2) Map< SocketUserId, SocketManager >
(3) Map< Receipient, SocketUserId >
interface Callback
{
void receipientAdded( Receipient r );
void receipientDeleted( Receipient r );
}
# 1 楼答案
在抽象层次上,你有:1
Thing
与nOtherThing
相关。你可以通过创建一个特殊的关系对象来建模,该对象引用Thing
,并包含对nOtherThing
的java.util.List<OtherThing>
引用。这会让你的域对象(事物)与关系信息保持一致。但是如果它看起来是对的,那么直接将java.util.List
添加到类Thing
(或子类)就更简单了。只有在需要建立关系时,列表变量才能保留为空,并用java.util.ArrayList<OtherThing>
填充# 2 楼答案
在每个
Receipient
中保留对SocketManager
的引用。这样,您就可以避免映射(它需要更多的内存,速度较慢,并且不会增加任何价值)在
SocketManager
中,保留Receipient
的列表。添加和删除Receipient
时,更新指向SocketManager
的指针在
SocketFacade
中,需要一个映射,它接受SocketUserId
并返回SocketManager
。该映射通过查询映射中的ID来填充。在所有经理都存在后,将收件人添加到每个经理中。这需要两个SQL查询这很容易用任何ORM工具进行映射
# 3 楼答案
既然SocketUserId和SocketManager之间存在1-1关系,那么就不能在SocketManager中添加对SocketUserId的引用,并在收件人中添加对SocketManager的引用吗
然后你会在你的门面上有一张包含收件人的地图,以及SocketManager的列表。在
sendData
函数中,您将从映射中获取收件人,并从该收件人获取对其SocketManager的引用问候
纪尧姆