在我阅读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中的行为。
答案 0 :(得分:3)
显然没有一种真正的方法来构建一个应用程序,但我自己的想法跟随......
我同意普通java bean 和域对象之间的主要区别在于行为。但我认为你真的应该在你的域对象中有行为,而另一个你冒anemic domain model的风险。使用域对象设计域模型,而不仅仅是作为getter和setter包的普通对象。如果它是域的一部分,那么它实际上可能会有一些相关的行为。
您的数据访问对象完全可以依赖于像Person这样的域对象 - 事实上我认为这完全是他们的目的。我将数据访问视为关系数据存储和对象模型之间的映射。您的简要实施片段实际上类似于存储库,这就是域和数据映射层之间的中介。
有一些争论是您应该避免在表示层中使用域对象,并且只将轻量级数据对象公开给客户端以供查看。 (例如,参见ASP.NET MVC应用程序中视图模型类的常见概念。)您的服务层实际上将从域对象转换为这些视图对象,并将它们提供给前端客户端。一个关键的论点是,如果某个未知客户端将要使用您的服务,您不希望他们拥有对您的域对象和所有业务逻辑的完全访问权限 - 您只是想为他们提供他们需要知道的显示内容给用户。如果您是自己的唯一客户,尽管这不是问题。
当然,您并不总是需要复杂的域模型。您可能更喜欢Active Record,其中域对象管理自己的持久性。您还可以查看诸如CQRS之类的内容,您可以完全绕过域模型以获取客户端的视图信息,直接从存储的数据视图直接到定制的视图类。 (然而,在命令方面仍然使用域模型。)
我的建议:如果它足够复杂,请执行以下操作: