0

在阅读了 Fowler 的 PoEAA 之后,我真的很困惑什么是设计数据访问层的好方法或自然方法。我曾经让数据访问对象返回一个简单的 java bean,例如:

public class Person {
    private long id;
    private String name;
    private Gender gender;

    //... setters and getters
}

而数据访问对象就像

public class PersonDataAccessImpl implements PersonDataAccess {
    public Person getPersonById(long id) throws DataAccessException {
        //... select the database
    }
    public void addPerson(Person person) throws DataAccessException {
        //... insert into the database
    }
    ...
}

Person 对象将在整个应用程序中使用,包括上面的数据访问层和 Web 表示层。但根据 PoEAA,数据访问层通常位于各层的底部。让DAO依赖bean对象(Person),这不是一个好办法吗,后面会用到领域层、服务层和表现层?以及如何设计域层,因为在我看来,域对象和简单的 java bean 之间的区别在于,简单的 java bean 只缺少域中的行为。

4

1 回答 1

3

显然没有一种真正的方法来构建应用程序,但我自己的想法如下......

我同意普通 java bean域对象之间的主要区别是行为。但我认为你真的应该在你的领域对象中有行为,否则你会冒着贫血的领域模型的风险。使用领域对象设计您的领域模型,而不仅仅是作为 getter 和 setter 包的普通对象。如果它是域的一部分,那么它确实很可能有一些相关的行为。

您的数据访问对象完全可以依赖于域对象(例如 Person)——事实上,我认为这完全是他们的目的。我将数据访问视为关系数据存储和对象模型之间的映射。您的简短实现片段实际上类似于存储库,它只是域和数据映射层之间的中介。

有一些观点认为您应该避免在表示层中使用域对象,并且只向客户端公开轻量级数据对象以供查看。(例如,请参阅 ASP.NET MVC 应用程序中视图模型类的常见概念。)您的服务层本质上将从域对象转换为这些视图对象,并将它们提供给前端客户端。对此的一个关键论点是,如果某个未知客户端将使用您的服务,您不希望他们拥有对您的域对象和所有业务逻辑的完全访问权限 - 您只想为他们提供他们需要知道的内容以显示给用户。如果您是您自己的唯一客户,尽管这不是问题。

当然,您并不总是需要复杂的域模型。您可能拥有更像 Active Record 的东西,域对象在其中管理自己的持久性。您还可以查看诸如 CQRS 之类的东西,您可以完全绕过域模型以将视图信息传递给客户端,直接从存储的数据视图转到定制的视图类。(但是,域模型仍然用于命令方面。)

我的建议:如果它足够复杂,请执行以下操作:

  • 具有具有行为的对象的域模型
  • 有一个数据访问层在您的域模型和数据存储之间进行调解(这将取决于您的域对象)
  • 有一个服务层,它公开您的应用程序的必要操作,以便您的客户端显示和回发数据
于 2013-01-22T21:31:47.083 回答