【Translation】接口 vs. 实体类
在设计.net程序架构的时候,我更倾向于使用接口而不是实体类在作为函数的参数。
我们来看看下面这个例子:
第一个方法public IList<Article> Get(),他调用数据库,并得到一个包含了查询结果数据集合的SqlDataReader,然后调用第二个方法private IList<Article> FillArticles(SqlDataReader reader)的将SqlDataReader中的结果添加到IList<Article>中。
public IList<Article> Get()
{
SqlConnection connection = new SqlConnection(_connectionString);
SqlCommand command = new SqlCommand();
command.Connection = connection;
command.CommandType = CommandType.StoredProcedure;
command.CommandText = "GetAllArticles";
SqlDataReader reader = command.ExecuteReader(CommandBehavior.SingleResult);
return FillArticles(reader);
}
{
SqlConnection connection = new SqlConnection(_connectionString);
SqlCommand command = new SqlCommand();
command.Connection = connection;
command.CommandType = CommandType.StoredProcedure;
command.CommandText = "GetAllArticles";
SqlDataReader reader = command.ExecuteReader(CommandBehavior.SingleResult);
return FillArticles(reader);
}
private IList<Article> FillArticles(SqlDataReader reader)
{
List<Article> articles = new List<Article>();
while (reader.Read())
{
Article article = new Article();
article.ArticleID = (int)reader["ArticleID"];
article.Title = reader["Title"];
article.Body = reader["Body"];
article.Published = (DateTime)reader["Published"];
articles.Add(article);
}
return articles;
}
{
List<Article> articles = new List<Article>();
while (reader.Read())
{
Article article = new Article();
article.ArticleID = (int)reader["ArticleID"];
article.Title = reader["Title"];
article.Body = reader["Body"];
article.Published = (DateTime)reader["Published"];
articles.Add(article);
}
return articles;
}
通过上面这个例子你可以发现,FillArticles方法需要一个SqlDataReader (这是一个实体类)。好,现在需求变了,现在数据都存储在了XML文件中,这个时候,我们得到就是XmlDataReader(实际没有这个类型)而不是SqlDataReader了。很不幸,你唯一能做的就是修改这块的源代码。
那么,我们怎么样才能避免这样的问题呢?我们假设SqlDataReader和 XmlDataReader都实现了IDataReader接口。我们只需要把代码修改成如下的样子即可解决开始遇到的问题了:
private IList<Article> FillArticles(IDataReader reader)
{
List<Article> articles = new List<Article>();
while (reader.Read())
{
Article article = new Article();
article.ArticleID = (int)reader["ArticleID"];
article.Title = reader["Title"];
article.Body = reader["Body"];
article.Published = (DateTime)reader["Published"];
articles.Add(article);
}
return articles;
}
{
List<Article> articles = new List<Article>();
while (reader.Read())
{
Article article = new Article();
article.ArticleID = (int)reader["ArticleID"];
article.Title = reader["Title"];
article.Body = reader["Body"];
article.Published = (DateTime)reader["Published"];
articles.Add(article);
}
return articles;
}
这就是使用接口作为方法的参数,还不使用实体类的好处;)