3层架构 - 在层之间传递数据

时间:2012-06-29 09:54:02

标签: c# .net layer three-tier

尝试实现3层(不是:层,我只是想在一台机器上逻辑地分离我的项目)架构我发现了很多不同的方法,我很困惑,最好的方法是什么(如果有的话) )在WinForms应用程序中进行此操作。

现在我毫不怀疑项目中应该存在的3个层:

  • UI(表示层)
  • BLL(业务逻辑层)
  • DAL(数据访问层)

UI 中,我放了所有的WinForms。必须还有一些逻辑用控件中的数据填充对象并将其传递给BLL层。

DAL 中,我想使用ADO.NET为数据操作添加类和方法,例如:

public class OrderDAL
{
    public OrderDAL()
    {
    }

    public int Add(Order order)
    {
        //...add order to database
    }

    public int Update(Order order)
    {
        //...update order in database
    }

    //...etc.
}

问题在于BLL和问题 - 我应该使用数据传输对象在层之间传递数据,还是应该通过整个类?

如果我选择使用 DTO ,那么我将创建对UI,BLL和DAL的引用的其他公共类Order

public class Order
{
    public int Id { get; set; }
    public DateTime Date { get; set; }
    public string Number { get; set; }
    public string CustomerName { get; set; }

    public Order ()
    {
    }
}

将逻辑分隔放入BLL:

public class OrderBLL
{
    public OrderBLL()
    {
    }

    public int Add(Order order)
    {
        OrderDAL orderDAL = new OrderDAL();
        return orderDAL.Add(order);
    }

    public int Update(Order order)
    {
        OrderDAL orderDAL = new OrderDAL();
        return orderDAL.Update(order);
    }

    //...etc.
}

这种方法在不同名称下使用:herehere 另一方面,一些“聪明人”和他们的追随者(如here)称之为Anemic Domain Model并抱怨它是一个不应该使用的糟糕设计和反模式。

专业人士:

  • DTO可以很容易地通过设计来表示数据库表,
  • 它清晰明了,只包含数据库所需的字段,
  • DAL不必参考BLL,

缺点:

  • 反模式(听起来可怕; P),
  • 违反OOP(方法中的分离属性),
  • 因为逻辑属于不同的类,所以当事情发生变化时可能更难维持。

所以,相反的方法是在层之间传递整个对象,比如here:没有DTO,只有BLL看起来像这样:

public class Order
{
    public int Id { get; set; }
    public DateTime Date { get; set; }
    public string Number { get; set; }
    public string CustomerName { get; set; }

    public Order()
    {
    }

    public int Add()
    {
        OrderDAL orderDAL = new OrderDAL();
        return orderDAL.Add(this);
    }

    public int Update(Order order)
    {
        OrderDAL orderDAL = new OrderDAL();
        return orderDAL.Update(order);
    }
}

专业人士:

  • 它是一个很好的封装对象,遵循OOP规则(我想;))。
  • 逻辑和属性都在一个地方,更易于维护和调试。

缺点:

  • 要使用该对象,DAL必须引用BLL(这不是3层图层应该如何做,不是吗?)。
  • 类可能包含一些未在数据库中使用的字段,以及来自数据库的某些字段(如Id)不代表“现实生活”对象。

所以,它看起来像我选择的任何东西,我会违反一些规则。那么什么是更好的方式,我应该选择哪个?也许还有其他方法我还没找到?

1 个答案:

答案 0 :(得分:8)

我不喜欢DTO,因为它们意味着创建一个很少或没有价值的双层次结构。

我也不喜欢让模型对象对自己的持久性负责的想法。我更喜欢单独的持久层。为什么?模型对象并不总是需要持久化才有用。业务逻辑和功能与持久性正交。

如果你有两个层,则可以保持单向依赖图:持久性知道模型,但模型不知道持久性。如果模型对象负责持久性,则最终会产生循环依赖。您永远不能在没有持久性的情况下测试或使用模型对象

我的建议?不要做DTO。打破一个单独的持久层。