Как обработать зависимости от введения в богатые модели предметной области?

В проекте веб-сервера с богатой моделью предметной области (прикладная логика находится в модели, не в сервисах), как Вы обрабатываете введение зависимостей в объекты модели? Каковы Ваши события?

Вы используете некоторую форму AOP? Как спрингская @Configurable аннотация? Время загрузки или время изготовления, переплетаясь? Проблемы Вы встретились?

Вы используете ручную инжекцию? Затем, как Вы обрабатываете различные сценарии инстанцирования (создание объектов через библиотеку [как В спящем режиме], создавая объекты с "новым"...)?

Или Вы используете некоторый другой способ ввести зависимости?

7
задан alexandrul 19 May 2010 в 09:11
поделиться

2 ответа

Чтобы удерживать свои доменные объекты чистыми, я избегаю, используя инъекцию на объектах объектов / агрегатов / значений, а скорее поместите их в службу или репозитории, если это необходимо.

Для этого мы использовали нормальную инъекцию конструктора пружины, чтобы облегчить тестирование.

Если вам нужно что-то вводить в ваши организации, одно предложение может быть написать строитель или завод и вставлять то, что вам нужно там.

2
ответ дан 7 December 2019 в 10:02
поделиться

Мы используем 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();

Мы не проводили никакого сравнения производительности. Пока мы просто не чувствовали необходимости в этом.

РЕДАКТИРОВАТЬ: так будет выглядеть класс человека:

@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, ...). Он просто переместился на свое место.

4
ответ дан 7 December 2019 в 10:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: