在n层系统中,数据访问层应该向业务层返回哪些对象?

13
如果你有一个名为Person(ID、Name等)的数据库表,数据访问层应该向业务层返回什么样的对象呢? 我认为应该是这样的:
//data access tier
public class DataAccess{

   public interface IPerson{
      int ID{ get; set; }
      string Name{ get; set; }
   }

   internal class Person : IPerson{
      private int id;
      private string name;

      public int ID{ get{return id; } set{ id=value; } }
      public int Name{ get{retutn name; } set{ name=value; }
   }

   public static IPerson GetPerson(int personId)
   {
      //get person record from db, populate Person object
      return person;  
   }
}

//business tier
public class Person : IPerson{
   private int id;
   private string name;

   public int ID{ get{return id;} set{id=value;} }
   public string Name{ get{return name;} set{name=value;} }

   public void Populate(int personId){
      IPerson temp = DataAccess.GetPerson(personId);
      this.ID = temp.ID;
      this.Name = temp.Name;
   }
}

但是这种方法似乎有点繁琐?是否有更优雅的解决方案?我应该从数据访问层返回一个DataRow到业务层中吗?

4个回答

21

在数据访问层(DAL)中,您无需重复类定义。

您可以在单独的程序集中创建业务实体作为“哑”容器,例如,您的Person类可以只是:

public class Person
{
    int ID { get; set: }
    string Name { get; set: }
}
然后,你可以给你的数据访问层(DAL)提供对业务实体层的引用。你的控制器对象,无论它们是在单独的业务逻辑层还是在UI层内,都可以调用DAL,它可以创建一个业务实体,从数据库中填充它并将其返回给你的控制器。
Imar Spaanjaars的这篇文章很好地解释了这个模式。

将DAL引用业务实体层会不会创建一个[不良的]双向依赖? - Matthew Dresser
不,业务实体层将不会引用DAL。它只是一个“愚笨”的容器对象的集合。从DAL请求它们的应用程序部分(UI或单独的业务逻辑层)应该位于汇编的另一部分,并且应该引用DAL和实体。 - Adam Ralph
Assembly A:类定义,只有字段和属性。领域程序集。 Assembly B:数据访问层。引用程序集 A。 Assembly C:用户界面。引用程序集 A 和 B。 - user47589
@yodaj007 - 正确。您还可以引入业务逻辑层(BLL),例如Imar文章中的“Manager”类。您的“domain assembly”相当于Imar的业务对象程序集(BO)。然后引用如下:UI->BO,UI->BLL,BLL->BO,BLL->DAL,DAL->BO。 - Adam Ralph

6

你的业务层不需要知道数据行 - 尽量将数据特定类留在数据层。这样可以减少耦合,并使您在以后更改持久性层时无需进行全面的重新架构。

要解决您的特定问题,您可以选择以下两种方式之一:

  • 在数据层中创建基本数据对象/实体,并将它们移交给业务层进行消费。
  • 或者,正如您所做的那样,创建DTO(数据传输对象),这些对象纯粹作为从数据层向更高层的更丰富的业务对象实现传输数据的手段。您可以将此作为领域模型中存储库模式的一部分来完成。

您可能还想考虑的另一件事是层次结构和分层 - 这会影响您对这些内容的思考方式。层次结构通常是物理的,换句话说,它们定义了进程之间的边界。层通常是逻辑的,它们将程序的功能分成松散耦合的单元。在这种情况下,您应该针对层进行设计。


1
如果您创建接口到DAO类并将它们放置在业务层中,您可以从数据访问层引用您的业务层。数据层中的DAO类返回来自业务层的对象。
您的业务层引用接口而不是直接引用数据访问对象。通过IoC容器(例如Castle Windsor)进行依赖注入将允许您实现此目标。
这种技术称为分离的接口,并在此处进行描述:

http://www.martinfowler.com/eaaCatalog/separatedInterface.html

我见过的关于这种技术最好的解释可以在Billy McCafferty撰写的NHibernate最佳实践文章中找到。

http://www.codeproject.com/KB/architecture/NHibernateBestPractices.aspx

这篇文章包含了很多关于NHiberbate的具体信息,但其中一半内容是有关设计应用程序松耦合和易于单元测试的实用信息。

0

由于每个层都必须与上层松耦合,因此将BL引用添加到DAL中不是一个好主意。 最好在DAL中定义数据模型并使用接口,在BL中创建业务实体。 根据我的经验,在DAL中使用存储库并在业务实体或业务流程中访问它更好。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接