Как я могу сохранить сложную сущность с объектами стратегии в JPA?

avatar
Czyhandsome
8 апреля 2018 в 01:34
1002
2
0

Я использую Spring boot JPA для разработки проекта DDD. Я использовал форму на основе аннотаций для сохранения объектов домена в DAO. Но теперь модель предметной области стала настолько сложной, что я решил применить шаблон стратегии к сущностям предметной области.

Вот пример:

@Entity
class ComplexEntity {
    @Id
    private String id;

    // ... other simple fields

    // Example of a strategy object
    // Which deals with complex logics
    private StrategyObject strategyObject;

    // Business methods here
    public void doLogic(OtherEntity other) {
        strategyObject.performOn(other);
        // other logics...
    }
}

Когда я выполняю рефакторинг объектов предметной области таким образом, форма становится такой серьезной проблемой, с которой я почти не могу справиться. Существуют ли какие-либо решения для сохранения таких сложных объектов домена?

Источник
Igor Stetsiura
8 апреля 2018 в 02:22
0

Как должен выглядеть StrategyObject в базе данных? Это отдельная таблица, относящаяся к текущему или одному/нескольким значениям в текущей таблице?

Czyhandsome
8 апреля 2018 в 07:27
0

Я хочу сделать несколько значений в текущей таблице, в основном потому, что объект стратегии часто берется из исходного класса, который имеет слишком много полей и логики. Абстракция объекта стратегии обусловлена ​​двумя причинами: 1. сокращение исходного класса; 2. упростить создание новых классов с изменением лишь небольшой части логики, в то время как другие остаются.

Guillem
8 апреля 2018 в 10:52
0

Как аннотируется StrategyObject? Для начала следует аннотировать StrategyObject с помощью @OneToOne в ComplexEntity. Включите код StrategyObject, чтобы понять, какие поля необходимо сохранить.

Czyhandsome
10 апреля 2018 в 07:15
0

StrategyObject — это всего лишь оболочка некоторых полей и методов, которые могут повторно использоваться или расширяться другими классами. Например: Исходный класс может иметь следующие вещи: class Original { private int a; частная строка b; public void doSomething() { // Сделайте что-нибудь с a, b... } class WithStrategy { private StrategyObject so; public void doSomething() { so.doSomething; }

Ответы (2)

avatar
EasterBunnyBugSmasher
12 апреля 2018 в 11:35
0

Я бы создал перечисление

public enum Strategy {

    public abstract StrategyObject getImplementation();

    STRATEGY_1 {
         public StrategyObject getImplementation() {
              return new Strategy1();
         },
    STRATEGY_2 {
         public StrategyObject getImplementation() {
              return new Strategy2();
         }
}

, а затем укажите ссылку на перечисление Strategy в вашей сущности:

@Entity
class ComplexEntity {
    @Id
    private String id;

    @Enumerated(EnumType.STRING)    
    private Strategy strategy;

    public void doLogic(OtherEntity other) {
        strategy.getImplementation().performOn(other);
    }

}

РЕДАКТИРОВАТЬ: Думаю, я пропустил ту часть, где стратегии могут иметь значительный объем конфигурации, которую необходимо сохранить. Но, возможно, это только начало.

Czyhandsome
18 апреля 2018 в 01:00
0

Вполне годно и удобно, когда в стратегии не нужно хранить никаких данных в БД, а только чистую логику. Но если мне нужно что-то сохранить в объекте стратегии, Enum-Solution недостаточно.

avatar
Igor Stetsiura
8 апреля 2018 в 12:02
0

К сожалению, это невозможно сделать с помощью JPA, но Hibernate поддерживает эту возможность.

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