【问题标题】:Does Mediator die when Colleague dies?同事死后调解员会死吗?
【发布时间】:2020-04-22 08:21:20
【问题描述】:

我有一个与 Mediator Design Pattern 相关的问题,它属于 GoF行为 类别。我正在尝试使用设计模式原则编写一个 C# 项目。 假设这是一个同事类:

abstract class Colleague
{
    Mediator mediator;
    // ...
}

还有一个中介类:

class Mediator
{
    List<Colleague> colleagueList;
    // ...
}
  • 我们可以有很多同事:c1、c2、c3、...
  • 还有一个调解员:调解员

调解员充当允许同事之间交流的中心点。 假设在我们的代码中,某个同事死了。 Mediator 对象也会死吗?

【问题讨论】:

  • 一个对象只有在没有更多引用时才会被 GC'ed。你说有多个同事和一个调解员。如果这意味着所有同事都引用了同一个调解器实例,那么调解器只会在最后一位同事“死亡”后被 GC(没有更多引用)。
  • @RufusL 旁注:在谈论 GC 处理的对象时,我不会使用“disposed”一词,因为“disposed”在 .NET 世界中通常具有特殊含义(.Dispose() 调用对象。 .. 与 GC 没有直接关系)
  • @AlexeiLevenkov 谢谢,已编辑

标签: c# class oop design-patterns mediator


【解决方案1】:

在 .NET 中,对象只有在没有更多“根”引用时才会“死亡”(收集垃圾)(例如,单独的循环引用不计算在内)。因此,只要 Colleague 被其他东西引用,它引用的 Mediator 就会保留。

【讨论】:

  • when there are no more references to them 我认为这需要修改为无法从根到达对象。如果您有两个相互引用的 A 和 B 类,但没有其他引用它们,它们仍然可以被收集。我想。我不是 100% 的。
  • @Amy 你是对的,100%。循环引用是不够的,您需要一个“根”引用,其中包括静态字段、活动线程/堆栈上的实时变量等(某处有一个结论性列表)。当 Delphi/Object Pascal 获得接口支持时,循环引用是一个痛苦,因为编译器“自动”插入了​​托管引用计数,但是如果你让两个对象(或更大的循环)相互引用,则没有一个对象曾经达到 0 个引用,您可能会像疯子一样泄漏内存。
  • 所以,如果我在main()中创建了一堆同事和一个中介,UI类也是一个同事,那么我启动程序Application.Run(UI);你认为这是安全和好的做法吗?它会导致循环引用吗?
【解决方案2】:

一个对象只有在没有更多引用时才会被垃圾回收。

您说有多个同事和一个调解员,但这个问题有点令人困惑。

书面部分表明(至少在我的解释中)所有同事都提到了一个调解员。如果是这种情况,那么调解员只会在最后一位同事“死亡”(没有更多引用)之后被 GC'ed。

但是,根据您的代码示例,Mediator 类本身在私有 List&lt;Colleague&gt; 字段中保存对所有同事的引用。如果是这种情况,则Mediator 类的生命周期不依赖于Collegue 类的任何(或所有)实例。 colleagueList 可以为 null 或空,只要在某处仍有对 it 的引用,Meditor 实例就会一直存在。

【讨论】:

  • 有点牵强,但我并不是白白地被称为“漏洞队长”。如果 Mediator 持有对 Colleague 的引用,并且该 Colleague 被垃圾回收,那将是因为不存在导致它的实时根引用。 Mediator 仍然持有对它的引用的事实意味着不存在引用 Mediator 的实时根引用。从这个意义上说,如果一个同事被 Mediator 引用“死亡”,那么 Mediator 也必须被视为死亡。正如我所说,伸展,但我喜欢伸展 :)
  • @LasseV.Karlsen var meditator = new Mediator { colleagueList = null }; 它死了吗?也许我对“死/死”这个词感到困惑。我也不清楚Mediator 是否拥有对colleagueList 中项目的only 引用,或者Colleage 实例是否是唯一引用Mediator 的事物。我可能应该看看设计模式... :)
  • 不,您的整个答案都是正确的,这只是关于如何解释他的问题或对问题的描述的延伸。如果您有一个 Mediator 实例,其中包含一个包含对一个或多个 Colleague 实例的引用的列表,并且这些 Colleague 实例现在可以收集,这必须意味着该 Mediator 实例也可以收集,否则那些同事实例不会。但这只是一个愚蠢的评论。别管我:)
  • 如果同事不仅死了,而是死了,然后立即取另一个新同事的值();这会好吗? @LasseV.Karlsen
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-10-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多