Я использую Spring boot JPA для разработки проекта DDD. Я использовал orm на основе аннотаций для сохранения объектов домена в 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...
}
}
Когда я реорганизую объект домена, подобный этому, orm становится такой серьезной проблемой, с которой я почти не могу справиться. Есть ли какие-либо решения для сохранения такого рода сложных объектов домена?
Я хочу сделать несколько значений в текущей таблице, в основном потому, что объект стратегии часто берется из исходного класса, который имеет слишком много полей и логики. Абстракция объекта стратегии существует по двум причинам: 1. сокращение исходного класса; 2. упростить создание новых классов с изменением лишь небольшой части логики, в то время как другие остаются.
Как аннотируется StrategyObject? Для начала, StrategyObject следует аннотировать с помощью @OneToOne в ComplexEntity. Включите код StrategyObject, чтобы понять, какие поля необходимо сохранить.
StrategyObject - это просто оболочка некоторых полей и методов, которые могут повторно использоваться или расширяться другими классами. Например: Исходный класс может иметь следующие элементы: class Original {private int a; частная строка b; public void doSomething () {// Делаем что-нибудь с a, b ...} class WithStrategy {private StrategyObject so; public void doSomething () {so.doSomething; }




К сожалению, это невозможно сделать с помощью JPA, но Hibernate поддерживает такую возможность.
Я бы создал перечисление
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);
}
}
Обновлено: Думаю, я пропустил ту часть, где стратегии могут иметь значительный объем конфигурации, которую необходимо сохранить. Но, может быть, это начало.
Это вполне уместно и удобно, когда в стратегии не требуется сохранять какие-либо данные в БД, а нужна только чистая логика. Но если мне нужно что-то сохранить в объекте стратегии, Enum-Solution недостаточно.
Как должен выглядеть объект StrategyObject в базе данных? Это отдельная таблица, относящаяся к текущему или одному / нескольким значениям в текущей таблице?