9

我已经看到这是各种代码库,并且想知道这是否普遍不受欢迎。

例如:

public class MyClass
{
   public int Id;

   public MyClass()
   {
      Id = new Database().GetIdFor(typeof(MyClass));
   }
}
4

7 回答 7

11

嗯..我不会。但是话又说回来,我的方法通常涉及不负责检索自己的数据的类。

于 2008-10-01T21:44:55.263 回答
11

有几个原因通常不被认为是好的设计,其中一些像导致困难的单元测试和处理错误的困难已经被提及。

我选择不这样做的主要原因是您的对象和数据访问层现在非常紧密地耦合,这意味着在其原始设计之外对该对象的任何使用都需要大量返工。例如,如果您遇到一个实例,您需要使用该对象而没有分配任何值来保存该类的新实例,该怎么办?您现在要么必须重载构造函数,然后确保所有其他逻辑都处理这种新情况,要么继承和覆盖。

如果对象和数据访问是分离的,那么您可以创建一个实例,然后不对其进行水合。或者,如果您有一个使用相同实体但使用不同持久层的不同项目,那么这些对象是可重用的。

话虽如此,我过去在项目中采取了更简单的耦合方式:)

于 2008-10-01T22:54:47.123 回答
7

这也将使为该类编写单元测试变得困难,因为您将无法强制该类使用 db 类的 Mock/Stub 版本。见这里: http ://en.wikipedia.org/wiki/Dependency_injection

于 2008-10-01T21:49:26.560 回答
7

如果您引用数据库连接,则可以使用一次性模式:

public class MyClass : IDisposable
{
    private Database db;
    private int? _id;

    public MyClass()
    {
        db = new Database();
    }

    public int Id
    {
        get
        {
            if (_id == null) _id = db.GetIdFor(typeof(MyClass));
            return _id.Value;
        }
    }

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

用法:

using (var x = new MyClass()) 
{
    /* ... */

} //closes DB by calling IDisposable.Dispose() when going out of "using" scope
于 2008-10-01T21:51:41.797 回答
4

是的,你可以做到,但这不是最好的设计,并且构造函数中的错误处理不像其他地方那样整洁。

于 2008-10-01T21:49:01.600 回答
1

这种方法我能想到的唯一问题是,来自数据库初始化的任何错误都将作为构造函数的异常传播。

于 2008-10-01T21:44:51.597 回答
-2

为什么有人想使用模拟对象/存根而不是真实的东西?你同意汽车制造商应该使用纸板模型进行碰撞测试吗?

于 2008-12-03T10:47:28.483 回答