2010-01-20 74 views
7

在具有丰富域模型(应用程序逻辑位于模型中,而不是服务中)的Web服务器项目中,如何处理将依赖关系注入模型对象?你有什么经验?如何处理注入到富域模型的依赖关系?

你使用某种形式的AOP?像Springs @Configurable注释一样?加载时间或建立时间weawing?遇到的问题?

您是否使用手动注射?那么你如何处理不同的实例化场景(通过库创建对象[如Hibernate],创建具有“新”的对象...)?

或者你使用其他方式注入依赖关系吗?

+0

http://stackoverflow.com/questions/2091749/domain-driven-design-and-transactions-in-spring-environment – Bozho 2010-01-20 11:21:08

回答

2

为了保持我的域对象清洁,我避免在实体/聚合/值对象上使用注入,而是在需要时将这些注入到服务或存储库中。

为此,我们使用普通的Spring构造函数注入来简化测试。

如果您需要向实体中注入某些东西,建议可以编写一个构建器或工厂,然后在其中注入您需要的东西。

4

我们使用Spring的@Configurable(和普通的new运算符一样),它的作用就像一个魅力。没有更多anemic domain models。最后,这是更加面向对象的设计,是不是:

Person person = new Person(firstname, lastname); 
// weird 
peopleService.save(person); 
// good (save is @Transactional) 
person.save(); 

Mail mail = new Mail(to, subject, body); 
// weird 
mailService.send(mail); 
// good (send is @Transactional) 
mail.send(); 

虽然我们没有做任何性能比较。到目前为止,我们根本没有觉得有必要这样做。

编辑:这是人类会是什么样子:

@Configurable("person") 
public class Person { 
    private IPersonDAO _personDAO; 
    private String _firstname; 
    private String _lastname; 

    // SNIP: some constructors, getters and setters 

    @Transactional(rollbackFor = DataAccessException.class) 
    public void save() { 
     _personDAO.save(this); 
    } 

    @Transactional(readOnly = true) 
    public List<Role> searchRoles(Company company) void{ 
     return _personDAO.searchRoles(this, company); 
    } 

    // it's getting more interesting for more complex methods 
    @Transactional(rollbackFor = DataAccessException.class) 
    public void resignAllRoles(Company company) { 
     for (Role role : searchRoles(company)) { 
      role.resign(); 
     } 
    } 
} 

// the implementation now looks like this 
personService.getPerson(id).resignAllRoles(company); 

// instead of this 
roleService.resignAll(personService.searchRoles(personService.getPerson(id), company)); 

这就是Spring配置:

<context:spring-configured /> 
<bean id="person" class="org.example.model.Person" lazy-init="true"> 
    <property name="personDAO" ref="personDAO" /> 
</bean> 

注:正如你看到的,还有服务周围,如以搜索对象(personService.getPerson(id)),但是对所有传递对象(例如人)进行操作的所有方法都被移至该类本身(即person.save()而不是personService.save(person))。该方法本身保持不变,并与任何基础数据访问层(纯JDBC,Hibernate,JPA等)一起工作。它只是移动到它所属的地方。

+0

你如何持续集成测试你的实体?普通的JDBC?因为如果你使用hibernate,这个策略是行不通的! – Arne 2010-05-19 10:15:40

+0

@当然它会。看到我的编辑为例。这个想法是,你只需将DAO注入到域对象中即可。然后将方法从服务移至类(通常是将此类的对象作为参数的所有方法)。其他一切都保持不变。 – sfussenegger 2010-05-19 13:27:25

+0

但是,如果您已经拥有personId(例如,您正在编辑某人)呢?然后你可以做一些像'personService.getPerson(personId).resignAllRoles(company);'或'roleService.resignAll(personService.searchRoles(personId,company));'第一个可能会做额外的不必要的查询来获得人物。 – 2014-01-09 17:55:10

0

您还可以查看下面的链接,这可以帮助很多。

软件体系结构和丰富域模型的实用观点描述了丰富域模型和软件体系结构在哪里见面。

此外,它介绍了如何配置,具有以下技术,框架和API的实现和JUnit这样的观点:

  1. 春天;使开发人员的生活更轻松
  2. JPA;用于对象关系映射
  3. AspectJ;充分体验Rich Domain Model
  4. JUnit;为您的富域模型

http://www.ruimtefotografie.org/forum/viewtopic.php?f=32&t=193