我继承了一个用Java编写的应用程序,它使用JPA来访问数据库。该应用程序使用了我之前未遇到的设计模式,我真的会对使用此模式的原因进行一些指导。像许多应用程序一样,我们有一个前端,中间件和后端数据库。通过DAO访问数据库。 DAO上的每个方法都加载一个实体-DTO,它只是一个POJO,只有getter和setter,然后实体-DTO被传递给一个实体本身,该实体具有改变实体状态的其他方法。一个例子[改变了类名以保护无辜者]
enum Gender
{
Male,
Female
}
class PersonDTO
{
private String mFirstName;
private String mLastName;
private Gender mGender;
...
String getFirstName() { return this.mFirstName; }
String setFirstName(String name) { this.mFirstName = name; }
// etc
}
class Person
{
PersonDTO mDTO;
Person(PersonDTO dto)
{
mDTO = dto;
}
String getFirstName() { return mDTO.getFirstName() }
String setFirstName(String name) { mDTO.setFirstName(name); }
// and so on
void marry( Person aNotherPerson )
{
if( this.getGender()==Gender.Female &&
aNotherPerson.getGender()==Gender.Male)
{
this.setLastName( aNotherPerson.getLastName() );
}
aNotherPerson.marry( this );
}
}
这在30个左右的实体类中重复,使用DTO加倍到60,我只是无法理解为什么。我理解(比特)关于转换的分离,我也理解(比特)关于基于EAO的设计与基于活动记录的设计之间的区别。
但这真的要走这么远吗?应该总是至少有一个" DB"只包含映射到数据库字段的getter和setter的对象?
答案 0 :(得分:1)
免责声明:对此主题有不同的意见,根据您的系统架构,您可能无法选择。
随着那个说...我已经看过这个模式之前实现过,而不是它的忠实粉丝,在我看来,重复大量代码而不增加任何实际价值。它似乎在使用像SOAP这样的XML API的系统中特别受欢迎,因为可能很难将XML结构直接映射到对象结构。在您的特定情况下,它似乎更糟糕,因为除了重复的getFirstName()/ getLastName()方法之外,还有业务逻辑(属于服务层)编码到pojo(应该是一个简单的数据传输对象)像DTO一样)。为什么pojo知道只有异性的人才能结婚?
为了更好地理解为什么,您能解释一下这些DTO的来源吗?是否有一个前端向控制器提交数据,然后将其转换为DTO,然后用于使用数据填充您的实体?
答案 1 :(得分:1)
它们也可能只是将JPA注释与富域对象分开使用。
所以我猜测有人不喜欢在一个类中使用JPA注释和丰富的域对象行为。有人可能也认为JPA注释和富域对象不应该在同一层(因为注释混合了关注点),所以如果你赢了这个论点,你会得到这种分离。
另一个你看到这种事情发生的地方是你想要从丰富的域对象中抽象出类似的注释(比如web服务中的jaxb注释)。
因此,意图可能是DTO作为从代码到数据库的序列化机制的一种,这与提到的here by martin fowler的意图非常相似。
答案 2 :(得分:0)
这似乎不是一个已知的模式。
一般
答案 3 :(得分:0)
我参与过一个项目,我们有一个DTO,其唯一目的是将信息从前端控制器传输到一些外观层。然后,外观层负责将这些DTO转换为域对象。
这种分层背后的想法是将前端(视图)与域分离。有时,DTO可以包含多个域对象以用于聚合视图。但是域层总是呈现干净,可重用,可缓存(如果需要)的对象。