3

我目前正在开发一个集成项目以连接两个不同的系统。
我的计划是设置一个 HTTP-API 以允许系统 A 通过 HTTP-POST 向系统 B 发出命令。
这些命令将用于向 SQL 服务器数据库发出 CRUD 指令以检索和更新会员卡数据(例如“创建会员” '、'更新成员资格'等),然后将数据作为 XML 返回到系统 A。我知道 n 层设计要求我应该有一个具有多个属性的 MembershipCard 类:

public class MembershipCard
{
    private string number;
    private decimal points;

    public string Number
    {
        get { return number; }
        set { number = value; }
    }

    public decimal Points
    {
        get { return points; }
        set { points = value; }
    }

连同调用 DAL 的几种方法:

    public string GetPoints(string cardnumber) 
    {
        return MembershipCardDB.BalanceRequest(cardnumber);
    }

但是,我在将这种方法证明为静态 DAL 类时遇到了一些困难,MembershipCardDB 似乎执行了我需要的所有工作(见下文):

    public static string BalanceRequest(string cardNumber)
    {
        string response = string.Empty;
        string sqlselect = 
            "SELECT Balance                         " +
            "FROM tbl_MemberShipCard                " +
            "WHERE Card_No = @cardNumber                 " +
            "FOR XML PATH ('Card'), ROOT('CardBalance')";

        using (SqlConnection connect = new SqlConnection("Data Source=TEST\\TEST;Initial Catalog=TEST;User Id=sa;Password=TEST"))
        {
            connect.Open();
            using (SqlCommand command = new SqlCommand(sqlselect))
            {
                command.Parameters.AddWithValue("@cardNumber", cardNumber);
                response = (string)command.ExecuteScalar();
            }
        }
        return response;
    }

通过简单地删除 MembershipCard 类并从数据库中提取数据并将其格式化为 XML 有什么我忽略的吗?

4

4 回答 4

2

关键是您应该能够独立于任何数据库接口或 xml 格式编写程序逻辑。将所有数据库内容放入加载和创建对象的单独类中。对对象做任何你想做的事情。最后将对象存储回数据库或 xml。但是,如果您的代码只是关于导入和导出数据,则可以删除额外的类。

顺便说一句,您可以MembershipCard使用自动实现的属性来简化类:

public class MembershipCard
{
    public string Number { get; set; }
    public decimal Points { get; set; }
}

我经常有一个静态DB

public static class DB
{
    public static string GetBalanceRequest(string cardNumber)
    {
        ...
    }

    public static MembershipCard LoadMembershipCard(string cardNumber)
    {
        ...
    }

    public static List<MembershipCard> LoadMembershipCards()
    {
        ...
    }

    public static void SaveMembershipCard(MembershipCard membershipCard)
    {
        ...
    }
}

你的MembershipCard班级可能有一个方法

    public string BalanceRequest()
    {
        return DB.GetBalanceRequest(this.Number);
    }

像这样,您将数据库操作和其他应用程序逻辑分开。

于 2012-10-02T20:40:24.143 回答
1

建筑是一件有趣的事情。在选择一个范式之前,最好准确评估你想要完成的工作。

有时 n 层设计可以在以后节省您的时间,但有时您今天必须编写的额外代码量是不值得的。从你说的情况看,你好像已经进入了后者阵营。

所以,回到我的第一句话,你应该问自己:你预见到需要将数据格式化 (XML) 与检索 (SQL 查询) 分开吗?

当然,在某些情况下您可能会这样做。例如,XML 非常冗长,并且包含许多您以后可能不需要的额外的非信息性数据。通过将自己与 SQL Server 如何发出 XML 联系起来,如果您决定使用 JSON,您将面临重写。

更进一步,XML 甚至 JSON 都适用于有限数量的数据,例如一次只传输几条记录,但是如果您开始一次传输数百或数千条数据,那么数据量很容易达到您想要的点通过网络发送类似于 CSV 文件的内容。同样,您将面临重写。

但是,如果您在可以插入新提供程序来处理各种格式要求的地方构建它,那么您将编写新代码而不是替换潜在的大块旧代码......而且同时支持多种格式也相当容易(XML、Json、CSV、Excel 等)如果格式与检索不紧密耦合。

扮演魔鬼的拥护者,如果我们谈论的是一个小型系统,那可能并不重要,因为由于格式更改而重写代码所花费的时间可能是微不足道的,此时我不会花时间构建 n 层模型.

希望对您有所帮助,最终我认为我们无法告诉您该走哪条路。

于 2012-10-02T21:23:49.707 回答
1

如果您专门公开 CRUD 操作,REST 接口可能是要走的路(请参阅Web API)。有了这条路线,我相信你有理由直接使用你的数据库类。这并没有真正违反 N 层方法 - Web 服务实际上充当数据层的接口。

您甚至可以更进一步,使用当前构建中的 OData 支持公开对您的服务的延迟执行查询。

主要问题是 Web API 仍处于测试阶段,并且会定期更改。例如,发布预览版中几乎没有 OData 支持。它在夜间构建中要先进得多。

于 2012-10-02T21:01:34.653 回答
0

n 层设计要求我应该有一个具有多个属性的 MembershipCard 类

我不确定这是否准确。我认为 n 层设计规定每一层只依赖于它下面的层。并且每一层不需要只依赖于它下方的层——你可以跳过关卡。因此,您的 Web 服务接口可以跳过域层并直接进入存储库。尽管即便如此,最好在中间添加另一个层,例如“应用程序”,它为您提供了添加额外非数据访问逻辑的空间,而不是让它泄漏到您的 UI/Web 服务中。

数据库访问类中的“Console.ReadLine”将 UI 与存储库混合在一起,因此这显然不好。另外,使用静态方法使得编写单元测试变得困难,所以这也不好。

查看... Eric Evans 的领域驱动设计。

于 2012-10-02T21:23:23.517 回答