这是实现这样的数据访问对象的好方法吗?

时间:2013-01-19 07:18:29

标签: design-patterns

在我阅读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只缺少域1中的行为。

1 个答案:

答案 0 :(得分:3)

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

我同意普通java bean 域对象之间的主要区别在于行为。但我认为你真的应该在你的域对象中有行为,而另一个你冒anemic domain model的风险。使用域对象设计域模型,而不仅仅是作为getter和setter包的普通对象。如果它是域的一部分,那么它实际上可能会有一些相关的行为。

您的数据访问对象完全可以依赖于像Person这样的域对象 - 事实上我认为这完全是他们的目的。我将数据访问视为关系数据存储和对象模型之间的映射。您的简要实施片段实际上类似于存储库,这就是域和数据映射层之间的中介。

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

当然,您并不总是需要复杂的域模型。您可能更喜欢Active Record,其中域对象管理自己的持久性。您还可以查看诸如CQRS之类的内容,您可以完全绕过域模型以获取客户端的视图信息,直接从存储的数据视图直接到定制的视图类。 (然而,在命令方面仍然使用域模型。)

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

  • 拥有行为
  • 的对象的域模型
  • 有一个数据访问层,可以在您的域模型和数据存储之间进行协调(这取决于您的域对象)
  • 有一个服务层,公开您的应用程序的必要操作,以便客户端显示和回发数据