如何处理将依赖项注入富域模型?

时间:2010-01-20 11:13:53

标签: java inversion-of-control domain-driven-design aop

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

你使用某种形式的AOP吗?喜欢Springs @Configurable注释?加载时间还是构建时间?你遇到的问题?

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

或者您是否使用其他方式注入依赖项?

3 个答案:

答案 0 :(得分: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,......)。它只是搬到了它所属的地方。

答案 1 :(得分:2)

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

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

如果你需要向你的实体注入一些东西,一个建议可能就是写一个建造者或工厂,并在那里注入你需要的东西。

答案 2 :(得分:0)

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

关于软件体系结构和富域模型的实用观点描述了富域模型和软件体系结构的相遇。

此外,它描述了如何使用以下技术,框架和API来配置,实现和管理此视图:

  1. 弹簧;让开发人员的生活更轻松
  2. JPA;用于对象关系映射
  3. 的AspectJ;完全体验Rich Domain Model
  4. 的JUnit;用于Rich Domain Model的集成测试
  5. http://www.ruimtefotografie.org/forum/viewtopic.php?f=32&t=193