2

跟进 MARC Gravells 在这个问题上的建议

我现在在我的代码中重复了几次这样的事情:

using (var conn = CreateConnection())
using (var dataCommand = conn.CreateCommand()) 
{
        conn.Open();
        [...]                        
} 

以下对于工厂方法是否正确CreateConnection()?还是容易出错?(注意:我只会从using指令中调用它)

SqlConnection CreateConnection()
{
    SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["IMS"].ConnectionString);
    return conn;
}

或者是否有必要修改这种方法并将其Open也包含在内?

4

2 回答 2

5

您的代码是静态工厂方法的典型示例。

工厂模式是软件设计模式的一部分,它是软件设计中给定上下文中常见问题的通用可重用解决方案。我可以建议您阅读Head First Design Patterns,这是一本非常好的入门书籍,可以理解设计模式。

关于您的代码的一些建议:

  1. 使工厂方法静态,它不使用任何实例变量等。
  2. 不相关但是,你不需要在你的工厂方法中使用局部变量,你可以直接返回连接。

现在您的方法如下所示:

static SqlConnection CreateConnection(){
    return new SqlConnection(ConfigurationManager.ConnectionStrings["IMS"].ConnectionString);
}

您可能想在调用 SqlConnection 的构造函数之前检查 ConnectionStrings["IMS"] 是否为空。此类中不需要进一步的错误处理,因为它不会启动连接。

假设您想返回一个打开的连接并以相同的方法处理连接错误:

static SqlConnection CreateConnection()
{

    if (ConfigurationManager.ConnectionStrings["IMS"] == null)
    {
        throw new Exception("Connection string not found in the configuration file.");
    }
    var sqlConnection = new SqlConnection(ConfigurationManager.ConnectionStrings["IMS"].ConnectionString);
    try
    {
        sqlConnection.Open();
    }
    catch (Exception exception)
    {
        throw new Exception("An error occured while connecting to the database. See innerException for details.", exception);
    }
    return sqlConnection;
}

如果需要,您可以创建自己的异常类以在以后处理这些异常。请参阅ASP MVC N 层异常处理。如果发生异常,您也可以返回 null,但请先检查“返回 null 是否设计错误? ”。

于 2012-08-05T15:21:36.923 回答
2

工厂和单身人士:

我的吐槽。欢迎指正!!

在功能上,我看到开发人员理解工厂模式的方式存在脱节。简单来说,工厂会并且应该提供产品。(例如:如果你有一个“汽车工厂”,它应该给一个“汽车”)。

话虽如此,只有当您不想暴露实例化逻辑并且需要创建不同的具体产品时,您才实施工厂模式。在您的情况下,如果您始终需要一个 SQL 对象(一种产品),那么为什么要使用 Factory? 您可以争论可扩展性和可伸缩性,但这是主观的。大多数公司只是长期使用 SQL Server 或 Oracle,而您不会使用您在产品中构建的可伸缩性。

  1. 我相信,您可以很好地使用单例模式(或)具有静态成员的更简单的类。
  2. 另一个重要的方法是 CloseConnection() 方法。在您的原始代码中,您使用using了 which 杀死和处置对象,但在您的新静态实现中,您可能想要构建它。
    public static void CloseConnection(SQLConnection conn)
    {
        if (conn.State == ConnectionState.Open)
        {
           conn.Close();
           conn.Dispose();
        }
    }

于 2012-08-10T16:08:10.850 回答