如何处理将依赖项注入到丰富的域模型中?

发布于 2024-08-18 07:44:18 字数 243 浏览 10 评论 0原文

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

你使用某种形式的 AOP 吗?喜欢 Springs @Configurable 注解吗?加载时间或构建时间的偏移?您遇到的问题?

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

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

In a web server project with a rich domain model (application logic is in the model, not in the services) how do you handle injecting the dependencies into the model objects? What are your experiences?

Do you use some form of AOP? Like Springs @Configurable annotation? Load time or build time weawing? Problems you encountered?

Do you use manual injection? Then how do you handle different instantiation scenarios (creating of the objects through an library [like Hibernate], creating objects with "new" ...)?

Or do you use some other way of injecting the dependencies?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

贪恋 2024-08-25 07:44:18

我们使用 Spring 的 @Configurable(以及常规的 new 运算符),它的作用就像一个魅力。不再有贫血域模型。最后,这是更加面向对象的设计,不是吗:

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();

不过我们还没有进行任何性能比较。到目前为止,我们根本不觉得有必要这样做。

编辑:这就是 person 类的样子:

@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,...)。它只是搬到了它所属的地方。

We use Spring's @Configurable (along with regular new operator) which works like a charm. No more anemic domain models. Finally, this is much more object oriented design, isn't it:

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();

We haven't done any performance comparison though. So far, we simply haven't felt the need to do so.

EDIT: that's how the person class would look like:

@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));

And that's the Spring config:

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

Note: as you see, there are still services around, e.g. to search for objects (personService.getPerson(id)) but all methods that operate on a passed object (e.g. a person) are moved to that class itself (i.e. person.save() instead of personService.save(person)). The method itself stays the same and works with any underlying data access layer (pure JDBC, Hibernate, JPA, ...). It has simply moved where it belongs.

半透明的墙 2024-08-25 07:44:18

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

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

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

To keep my domain objects clean I avoid using injection on the entities/aggregates/value objects and rather put those in the services or repositories if needed.

For this we used normal Spring constructor injection to ease testing.

If you need to inject something into your entities one suggestion could be to write a builder or factory and inject what you needed there instead.

沩ん囻菔务 2024-08-25 07:44:18

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

软件架构和富域模型的实用观点描述了富域模型和软件架构的交汇点。

此外,它还描述了如何使用以下技术、框架和 API 配置、实现和联合此视图:

  1. Spring;让
  2. JPA 开发人员的生活更轻松;用于对象关系映射
  3. AspectJ;充分体验
  4. JUnit丰富领域模型;用于富域模型的集成测试

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

You can also check the link below, which can help out a lot.

A Pragmatic View on Software Architecture and the Rich Domain Model describes where the Rich Domain Model and Software Architecture meet.

Furthermore it describes how to configure, implement and junit this view with following techniques, frameworks and api's:

  1. Spring; to make life easier for a developer
  2. JPA; for Object Relational Mapping
  3. AspectJ; to fully experience the Rich Domain Model
  4. JUnit; for integration testing of your Rich Domain Model

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文