2

我的问题:如何以更好的方式设计所描述的类而不担心数据完整性?

我有一个类 Player-Container 和 Player。Player-Container 或多或少是一个集中的播放器“数据容器”,用于许多线程,它们都具有指向此类的指针。TBB 库为只读和写入提供了锁定机制。我有一些伪代码来反映我当前的设计:

Class: Player-Container 
Method: CreatePlayer, RemovePlayer , LoginUser, VerifyUser

Class: Player
Method: None its a pure data container

现在对我来说,我开发得越多,在“顶级容器”上拥有这些功能似乎是错误的,但我似乎没有解决这个问题,因为容器将确保我可以锁定对象,以便没有并行访问可以修改用户(例如,用户构建某些东西并发送此请求两次,资源减少两次而不是一次)。

我想拥有的:

Class: Player-Container
Method: CreatePlayer, RemovePlayer

Class: Player
Method: LoginUser, VerifyUser,....

我的问题,我如何实现这一点并且仍然保存数据完整性,我应该只使用 hash_map 作为“索引”并构建“播放器”级别锁定吗?有一些意见和建议会很酷。最让我烦恼的是 PlayerContainer 实际上需要了解很多关于 Player Class 的信息,如果我更改一个属性,我必须在 Container 中重新编码很多。

如果有什么不清楚的地方请询问。

4

2 回答 2

2

听起来您在设计和锁定方面确实有两个问题,并且在封装和内聚方面显然存在一些设计张力。

从 api 的用户看来,只需要处理“Player-Container”类来添加/删除/登录玩家当然很好。

我会考虑在 Player-Container 上保留正面的方法以保持简单。但是,我也可能会添加辅助类或辅助函数来实现它们,以确保 Player-Container 类中的代码非常少。如果您愿意,也可以将这些作为方法添加到播放器类中。

如果您还没有阅读Scott Meyer 的这篇关于在哪里放置函数的文章,那么它可能值得您花时间阅读。

第二个问题是关于锁定的,即容器或播放器类上的锁应该放在哪里。

这里有选择,但请记住,您需要同步容器和单个类中的数据。因此,如果您使用并发容器来保存播放器并避免对播放器容器类进行重量级锁定,那么您肯定需要确保播放器类是同步的,特别是如果您允许多个线程对同一个播放器进行操作。

这样做时要小心,不要将单个方法锁定在播放器上,而是锁定整个播放器,以确保您不会交错不兼容的功能,即您真的不想要LoginUser 要与 RemoveUser 在同一用户上同时运行,您可能希望它们一个接一个地序列化和运行。

于 2012-10-08T19:46:26.413 回答
1

我不知道 TBB 库的特定功能,但一般来说,您可以构建类似类的东西SharedObject<Player>来公开Player实例以及可以使用 SharedObjectAccessor 对象单独访问的锁对象(例如读/写互斥锁)处理正确应用锁。

template<typename T>
class SharedObjectAccessor;

template<typename T>
class SharedObject
{
public:
    SharedObject(const T& initial = T())
    : managedObject(initial)
    {}

private:
    friend class SharedObjectAccessor<T>;

    const T& read() const { return managedObject; }
    T& write() { return managedObject; }
    ReadWriteMutex lock;
    T managedObject;
};

template<typename T>
class SharedObjectAccessor
{
public:
    SharedObjectAccessor(SharedObject<T>& ref)
    : sharedObject(ref)
    {}

    ~SharedObjectAccessor() { sharedObject.lock.unlock(); }

    const T& get() const
    {
        sharedObject.lock.lock_read();
        return sharedObject.read();
    }

    T& set()
    {
        sharedObject.lock.lock_write();
        return sharedObject.write();
    }

private:
    mutable SharedObject<T>& sharedObject;
};
于 2012-10-08T20:02:45.953 回答