设计最佳实践 - 对象应该拥有传递给构造函数的内容吗?

时间:2011-09-24 06:26:14

标签: oop

我有以下课程:

public class SqlCeEventStore: EventStore
{
  private EventStoreDB db;

  public SqlCeEventStore(EventStoreDB db)
  {
    this.db = db;
  }

  public void Dispose()
  {
    db.Dispose();
  }
}

我的问题是这样的:我是否正确地将EventStoreDB部署在我的类的Dispose方法中,因为它是在构造函数中传递给它的(因此,可能会在以后重用)我的班级被处理了)?

也就是说,如果我处理它,我要求正确使用我的班级:

using (var store = new SqlCeEventStore(new EventStoreDB)){
{
  //...
}

但是我可以看到正在使用这个替代调用:

using (var db = new EventStoreDB())
using (var store = new SqlCeEventStore(db))
{
  //...
}

在这种情况下,我应该EventStoreDB类中处理SqlCeEventStore

对于一种风格或另一种风格,是否有任何争论?我想选一个并坚持下去,我宁可不要翻硬币:)。

5 个答案:

答案 0 :(得分:2)

一般来说,这没有规则,但是我同意,因为对象是在你的范围之外创建并传递给你的,所以你不拥有它。

如果您已创建它,那么您应该拥有做任何您喜欢的任何权利(记录调用者的预期行为)

这是经典的composition vs aggregation内容。

答案 1 :(得分:1)

如果EventStoreDB由SqlEventStore拥有(即它是其组成的一部分),它应该由SqlEventStore类构造或与之合并。

如果它的使用超出了SqlEventStore生命周期的范围,那么它应该由外部代码创建和处理。

答案 2 :(得分:1)

这里没有一般规则,恕我直言,也不应该有一个。不同的物体具有不同的寿命,最通用的指导方针是确保物体根据其寿命进行一致管理,并且寿命尽可能短。

您可以尝试使用以下内容作为指导(但不要害怕在需要时偏离):在与分配对象相同的范围内处置对象。本指南适用于许多场景,它正是using语句简化的内容。

如果您有长寿命的物品没有明显的处理点,请不要担心。这很正常。但是,问问自己:我是否真的需要这个对象才能生存下去?还有其他方法我可以对此进行建模以缩短使用寿命吗?如果你能找到另一种缩短生命周期的方法,那通常会使对象更易于管理,应该是首选。

但同样,这里没有任何“一条真正的规则”。

答案 3 :(得分:0)

不能选择一个并坚持下去。用户总是可以选择他想要的东西。

但是,请记住,作为处理通过构造函数传递的对象的类,您不负责任。


注释

讨论是非常愚蠢的,因为if you want to impose initiation of the class using *new SqlCeEventStore(new EventStoreDB))*那么为什么不删除这个EventStoreDB参数并在构造函数中实例化变量db。

解决方法

有一个解决方法 - 检查这个:

public myClass {
    //do not make the constructor public //hide it
    private myClass(EventStoreDB db){
        this.db = db;
    }
    //make a public constructor that will call the private one in the way you want
    public myClass(){
        this(myClass(new EventStoreDB()));
    }
}

答案 4 :(得分:0)

我建议如果可以合理地想象构造对象是宇宙中对传入对象感兴趣的最后一件事情,以及其他东西想要继续使用传递对象的情况-in对象在构造函数完成之后,可能需要一个构造函数参数,该参数指定新对象是否应该获取传入的对象的所有权。

请注意,如果构造的对象将获取传入对象的所有权,则必须确保即使构造函数抛出异常也将处置该对象。一种方法是将构造函数调用包装在一个例程中,该例程将在“finally”块中处理传入的对象,除非构造函数已成功完成。