2011-09-24 29 views
4

我有以下类:设计最佳实践 - 对象应该拥有传递给它的构造函数的东西吗?

public class SqlCeEventStore: EventStore 
{ 
    private EventStoreDB db; 

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

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

我的问题是这样的:我在我班上的Dispose方法处置有关EventStoreDB纠正,因为它传递给它的构造函数(因此,可能可以想像,在我的课程被处理后重用)?

也就是说,如果我处理它,我授权,我班的正确用法是:

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

但我可以看到使用这种替代电话:

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

在这种情况下,我应该不是SqlCeEventStore类处置EventStoreDB

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

回答

2

一般是没有规则这一点,但肯定我会同意,因为对象是你的范围之内创建并获得通过对你来说,你不拥有它。

如果你创造了它,那么你应该有完全的权利做任何你喜欢(有记录的来电者的预期行为)

这是典型的composition vs aggregation东西。

+0

啊......谢谢,我必须承认,“构图vs聚合”的区别对我来说从来不清楚 –

+0

@ Marcel:是的,这是一个难以理解的棘手的定义,你的情况就是看到它的方式,顺便说一句,现在很清楚了;) – Nrj

+0

是的,它是:)我将这个标记为公认的答案。 –

1

如果EventStoreDB由SqlEventStore(即它的组成部分)所有,它应该被构造或合并SqlEventStore类。

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

+0

好点。我更喜欢在构造函数中注入一个类所依赖的对象,所以我不能这样做,但如果没有这个规则,你会是正确的。 –

1

这里没有一般规则,恕我直言,不应该有一个。不同的物体具有不同的寿命,最一般的指导方针是确保物体的寿命是一致的,寿命尽可能短。

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

如果你有没有明显处置点的长寿命对象,不要担心。这很正常。但是,问问自己:我真的需要这个对象来生活吗?有没有其他的方式可以模拟这个使寿命更短?如果您可以找到另一种缩短寿命的方法,那么通常会使对象更易于管理,因此应该是首选。

但是,在这里没有任何“一个真正的规则”。

0

不能挑一个,坚持下去。用户可以随时选择他想要的。

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


的未来是非常愚蠢的讨论,因为if you want to impose initiation of the class using *new SqlCeEventStore(new EventStoreDB))*那么你为什么不删除此EventStoreDB参数和实例构造函数里面的变量分贝。

解决方法

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

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())); 
    } 
} 
+0

我不喜欢类中的new对象,而是在构造函数中传递依赖关系。你写它的方式是有效的,但它使'myClass'难以重用。 –

+0

其实......如果一个班级扩展你的班级,他将不得不使用超级班,这就是全部(: –

0

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

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