我正在为一家小公司开发一个简单的内部ASP.NET应用程序。我设计了数据访问层,因此它与数据库无关。
我有以下内容:
最后,我有一个静态类,它为要调用的数据访问类创建一个IDataHelper。将来它将根据配置文件中指定的数据库创建适当的帮助程序。现在它只是硬编码来创建一个MySqlHelper:
public static class DataHelperContainer
{
private static IDataHelper dataHelper;
public static IDataHelper DataHelper
{
get { return dataHelper; }
}
static DataHelperContainer()
{
string connectionString = ConfigurationManager
.ConnectionStrings["myapp"].ConnectionString;
// Support for other databases will be added later.
dataHelper = new MySqlHelper(connectionString);
}
}
我的问题是:
对于长篇文章和多个问题感到抱歉。 :)
谢谢!
答案 0 :(得分:4)
看起来Strategy pattern.使用策略模式可以在程序运行时更改底层功能,并且能够创建新功能而无需更改数据层的基本流程。 [通过IHelper接口保证功能]
答案 1 :(得分:2)
您可以将其命名为DataHelperFactory。
这是一个很好的模式。你肯定不想在整个地方泄漏像ConfigurationManager.ConnectionStrings["myapp"].ConnectionString
这样的东西!一个错误是它是静态的,这使得使用它来测试任何代码变得很困难。
这就像工厂模式或服务定位器(不是策略)。
目前,您的代码将如下所示:
public class MyClass
{
public void DoSomething()
{
var helper = DataHelperFactory.Create();
helper.ExecuteNonQuery("some sql");
}
}
这不容易测试,因为您必须修改app.config才能更改测试中返回的帮助程序。也许你想测试当helper.ExecuteNotQuery抛出异常时会发生什么。
使用依赖注入,您的类将更改为:
public class MyClass
{
private IDataHelper helper;
public MyClass(IDataHelper helper)
{
this.helper = helper;
}
public void DoSomething()
{
helper.ExecuteNonQuery("some sql");
}
}
这里的权衡是,现在你必须处理在调用上下文中提供IDataHelper依赖关系。这是Unity,Windsor和StructureMap等IoC容器的输入位置。这虽然比较复杂,但在您的情况下可能不值得。
使用工厂(甚至是静态)非常棒。它允许您使用其他模式(如装饰器)来添加其他行为。考虑一种情况,您希望清理sql字符串,并确保没有任何错误发送到您的数据库:
public class SanitizingDataHelper : IDataHelper
{
private IDataHelper helper;
public SanitizingDataHelper(IDataHelper helper)
{
this.helper = helper;
}
public void ExecuteNotQuery(string sql)
{
sql = EscapeHarmfulSql(sql);
helper.ExecuteNonQuery(sql);
}
private string EscapeHarmfulSql(string sql)
{
...
}
}
你的工厂可以做这样的事情:
public class DataHelperFactory
{
public IDataHelper Create()
{
...
var helper = new MySqlDataHelper(connectionString);
return new SanitizingDataHelper(helper);
}
}
答案 2 :(得分:1)
对于数据访问类,它似乎可能是数据访问对象(DAO)模式,但我不确定您是如何实现它的。 Andy West是对的,你肯定有一个策略模式。