在构造函数中返回一个新对象或初始化成员?
我们有一个数据提供程序类,它返回数据库中每个聚合的存储库。在构造函数中返回一个新对象或初始化成员?
让我们考虑以下情形:
public class DataProvider {
public IBookRepository Books { get { retun new BookRepository(); } }
public IAuthorRepository Authors { get { retun new AuthorRepository(); } }
}
正如你所看到的,我们每次都返回给定对象的新实例,我们调用成员:DataProvider.Books.DoBANANAS();
与
public class DataProvider {
public IBookRepository Books { get; }
public IAuthorRepository Authors { get; }
public DataProvider()
{
Books = new BookRepository();
Authors = new AuthorRepository();
}
}
会调用DataProvider.Books.BANANAS();现在CPU /内存很少?
正如我刚刚实施这两个版本,他们出人意料地工作!我的经验告诉我,Version 1 Sucks。然而,我有足够的时间来充分优化和实施最终产品。 (这是在研究组中工作的好处之一)
显示的实现在构建和管理对象的方式上有所不同。在第一个示例中,每次在DataProvider
上调用属性时都会创建一个新的存储库。如果存储库保存任何状态(例如,获取对象的缓存),则与第二个示例相比,您将获得非常不同的行为,因为每次都会将此状态重置为默认值。
从你说这两个版本的工作的事实,我会冒险猜测存储库对象不保持状态,只是代理数据库调用。在这种情况下,它可能没有太大的区别。
但是,两种方法的性能和内存配置文件有很大不同。虽然过早的优化是一件坏事,而且往往是浪费时间,但我不会这样说,因为在每个属性调用上创建一个新的存储库显然可能是后来的性能问题,或者如果您引入了更严重的错误,状态到存储库中。创建较少的对象最终会减少垃圾回收器的压力,但除非您创建了数百万个对象,否则这种差异可以忽略不计。
总之,第二个例子是前进中的更好的例子,考虑到现在我看不出真正的问题。
感谢您的回复。你猜对了,我的仓库根本没有任何状态。 另一个问题:将使DataProvider“静态”有所作为? 每当我需要从数据库或任何其他提供者访问某些数据时,我都不需要创建和实例化DataProvider。 – 2010-06-18 06:23:11
这取决于。它可能会使得更容易获得一个'DataProvider',但通过将其作为一个静态实例,它会使测试变得更加困难。 – adrianbanks 2010-06-18 08:32:23
在阅读了更多关于该主题(有假期,这就是为什么迟到的回应)之后,我发现我无意中试图实现'UnitOfWork'原则。这正是我研究多一点后想要的,我发现这正是我所期待的。 再次感谢您的伟大答案! – 2010-07-02 14:52:36
您的第一个示例每次创建一个新的XXXRepository对象实例,其中第二个将句柄返回到已存在的句柄,因此第二个句柄应该更好地执行并且使用更少的CPU,因为不需要分配新的内存。
更大的问题是,除非存储库类完全是静态的,否则这两种情况会产生完全不同的结果。如果存储库类是某种数据库的接口,那么在选项2的作用下,选项1不需要是线程安全的。
这两个示例在语义上不完全相同。他们有*非常*不同的行为,不仅仅是内存使用或速度上的一些细微差别。我想你不打算第一个做什么。 – dtb 2010-06-17 22:01:29
这两个版本都有很大不同的行为(至少在您的示例提供的细节层面) - 可能不仅仅是比较两个解决方案做不同的事情。你应该首先决定确切的行为和语义,然后才考虑性能(当且仅当它是一个实际问题)。 – 2010-06-17 22:09:02