DDD + hibernate +与soa集成

时间:2012-12-02 17:23:48

标签: hibernate domain-driven-design soa

起初我们有一个像

这样的模型
class Person extends EntityBase<Person, PersonNumber>{
 private PersonNumber personNumber;
 private String name;
 private Contact contact;
 private String educationLevel;
}
class Contact extends ValueObjectBase<Contact> {
  private String phone;
  private String address;
  private String contactPerson;
}

但是现在我们必须与另一个系统名称“System DC”集成,原始人员表被拆开,personNumber,名称,电话,地址栏现在移动到“System DC”。并且“SystemDC”为我们提供数据库视图“DC_PersonView”以供查询。如果我们需要创建一个人,我们必须从“SystemDC”调用webservice。

所以我们定义了一个像DOD一样的

 class PersonDTO{
 private PersonNumber personNumber;
 private String name;
 private String phone;
 private String address;
 }

计划1:

  1. 重构人员到IPerson界面
  2. 定义PersonWrape类

    class PersonWrape implements IPerson {
     private Person person;
     private PersonDTO personDTO;
    }
    
  3. PersonWrape存储库中的
  4. void SavePerson(IPerson person) {
      systemDC.saveWebservice(person.getPersonDTO);
      personRepository.save(person);// map the column not in systemDC like  educationLevel to our person table.
      }
    
  5. 计划2:   只修改personRepository:

        void SavePerson(IPerson person) {
          PersonDTO personDTO = PersonDTO.fromEntiry(person);
          systemDC.saveWebservice(personDTO);
          personRepository.save(person);// map the column not in systemDC like  educationLevel
          }
    

    但查询人将是残缺的......

    在这种情况下我们如何建模?请给我们一些建议。

2 个答案:

答案 0 :(得分:1)

使用DTO时非常棒,并且在使用SOA时不要公开域模式。最后还有其他任何事情(试图在客户端应用程序中使用域模型)。

但问题是您尝试将域模型公开为CRUD SOA服务。您不能让SOA服务更改任意实体的任何字段。它必须遵循域模型以及您在其中定义的方法和服务。

例如。如果在User类中有一个名为CalculateAge的方法,则创建一个名为CalculateUserAge的SOA方法,而不是名为UpdateUser的方法。

答案 1 :(得分:0)

看起来你有两个有界上下文(BC)之间的集成场景。在这些场景中,通常可以识别可以确定如何传播实体更改的关系BC。

在您的用例中似乎您有一个人的概念(每个人在BC之间共享一个身份),但您有两个不同的BC,其中一个人在每个BC中显示包含和管理不同的人数据。然后,您讨论的保存操作实际上是两个保存操作,每个BC一个。每个BC都保存它感兴趣的信息。如果您有一个用例,例如接受两个BC的人员信息的UI表单,该用例应该明确地向两个BC发送save命令。您的计划2最接近此方法,但我不会将该代码放在存储库中。相反,我会直接从表示层或应用程序层调用两个不同的服务。

您还可以考虑的是您的原始BC(我们称之为 A )和System DC 之间是否存在某种下游关系。例如,如果 DC 是人员数据的A的下游,那么您可以实现事件驱动的方法,而不是在保存期间显式调用这两个服务。使用此方法, A 会发布有关人员数据更改的事件, A DC 之间的集成点会订阅这些事件并进行 DC 中的适当修改。请注意,此方法通常为eventually consistent。总的来说,事件驱动的方法更复杂,但也更灵活。