gpt4 book ai didi

.net - 提供线程安全添加、删除、迭代集合到各种对象的包装器的最佳名称是什么?

转载 作者:行者123 更新时间:2023-12-03 12:57:43 25 4
gpt4 key购买 nike

这是一个有点奇怪的场景。我有一门课很快就变成了上帝课。它做得太多了。突然间我违反了 SRP。该类负责X和Y和Z,哦和A,还有B,别忘了C。所以我决定重构它。它变得这么大的原因是因为该类对一个集合做了很多工作,我已经做了很多工作来同步对它的访问,因为它是一个使用 ReaderWriterLockSlim 的多线程系统。

所以我确定了主要职责。有一个部分为集合提供数据。有时它可能需要在集合中创建一个新元素。我有一个对象可以清除计时器上的集合。因此,当计时器过去时,我会寻找可以从集合中删除的元素。然后我有一个需要从集合中获取东西的对象。它需要向集合中的每个项目询问东西,所以它需要迭代。

以前,对象自己完成所有这些工作。在锁定方面易于管理。单元测试并不容易。太多的事情发生,太多的 mock 。这太恶心了。将其分解为多个部分使单元测试更容易,但它使锁定变得更加困难。

所以每个部分,喂食器,清洁器和检索器都需要这个对象的一个​​实例。所以我应该将它注入(inject)构造函数中,然后我可以模拟它并且测试很容易。但现在因为集合在许多对象之间共享,所以我不能让每个对象直接访问它。我需要提供一种同步包装器。

我在想,当进料器要求集合中的新项目时,包装器会锁定集合,创建一个新项目,将其提供给进料器并通知清洁工集合中有新项目。清理器将该项目添加到其集合的副本中。

当清洁器运行时,它会遍历它的集合版本,当它找到可以删除的东西时,它会将其从集合中删除并通知包装器,包装器通知将其从其集合中取出的馈线。检索器使用 foreach 循环。所以包装器可以实现IEnumerator和IDispose。然后,当创建枚举器时,我可以锁定集合,当它被处理时,我可以退出锁定。

  • 我想做的事情有设计模式吗?
  • 有一个更好的方法吗?
  • 这个包装器的好名字是什么?

  • 我想到了以下几点:
  • 提供者(但它不仅仅是提供)
  • 维护者(有点模糊)
  • 同步器(我最喜欢这个)
  • 最佳答案

    我认为您对 Provider、Maintainer 和 Synchronizer 的想法听起来不错……我不知道这种情况下的开箱即用设计模式,所以您的想法似乎是合理的。

    现在,我认为我可以帮助您的部分是迭代。首先,您必须为您的收藏创建一个包装器。包装器将简单地包装集合的所有标准方法。例如:

    public void Add(Object obj)
    {
    lock(sync)
    {
    _collection.Add(obj);
    }
    }

    其次,如果你想锁定你关注的枚举器 this example .

    我不喜欢让垃圾收集器决定何时解锁同步对象的想法,所以在我个人看来,我宁愿以一种乐观的方式去做:
    1. 将集合中的每个元素复制到一个新集合中。
    2. 返回新集合的枚举数。
    3. 遍历枚举器时,对原始集合进行所有修改。

    这是示例:
    // In your Collection wrapper you need to provide an enumerable copy:
    public IEnumerator<T> GetEnumerator()
    {
    lock(sync)
    {
    Collection copy = new Collection():
    foreach(Object element in collection)
    {
    copy.Add(element);
    }

    return copy.GetEnumerator();
    }
    }


    // In your Maintainer's cleanup method you will do the following:
    public void TimedCleanup()
    {

    // You don't have any contention on the original collection.
    foreach(Object element in originalCollection)
    {
    if(shouldDeleteElement)
    {
    // Not a problem if somebody already iterated over
    // the collection and removed the same element.
    originalColection.Remove(element);
    }
    }
    }

    我希望它能回答你的问题:)。

    关于.net - 提供线程安全添加、删除、迭代集合到各种对象的包装器的最佳名称是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2341872/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com