TL/DR: Вопрос: Допустимо ли в DDD хранение интерфейсов (реализаций во время выполнения) в объектах домена?
У меня есть агрегат, который я хотел бы использовать во внешних сервисах. интерфейсы (постоянство, издатели событий и т. д.):
@AllArgsConstructor
@Getter
public class Place {
private PlaceId placeId;
private String name;
private Boolean locked;
// other fields...
private final PlacePersistenceService placePersistenceService;
private final PlaceEventPublisher placeEventPublisher;
public void save() {
placePersistenceService.persist(this);
placeEventPublisher.publishPlaceSaved(this);
}
public void delete() {
if(!this.locked) throw new DomainException("Place is locked, and can't be deleted!");
placePersistenceService.deleteById(this.placeId.getValue());
}
public FullPlaceDto castToFullDto() {
// ... mapping
}
// other methods...
}
Не обращайте внимания на аннотации Lombok в классе домена — я использовал их здесь для простоты.
Агрегат Place имеет вид создано созданной извне фабрикой:
@Service
@RequiredArgsConstructor
public class PlaceFactory {
// these two are injected with implementations by Spring
private final PlacePersistenceService placePersistenceService;
private final PlaceEventPublisher placeEventPublisher;
public Place ofName(String name) {
return new Place(PlaceId.of(UUID.randomUUID()), name, false, placePersistenceService, placeEventPublisher);
}
Интерфейс в том же доменном пакете, что и агрегат:
public interface PlacePersistenceService {
PlaceDb persist(PlaceDb placeDb);
Optional findByPlaceId(UUID placeId);
void deleteById(UUID id);
}
И внешняя реализация в другом месте (например, пакет инфраструктуры):
public class PlacePersistenceServiceJpa implements PlacePersistenceService {
@Override
PlaceDb persist(PlaceDb placeDb) {
// ... implementation
}
}
Это позволяет мне очень легко использовать домен:
@PostMapping
public ResponseEntity createPlace(@RequestBody PlaceCreateRequest request) {
Place place = placeFactory.ofName(request.getPlaceName());
place.save();
return ResponseEntity.ok(place.castToFullDto());
}
Подробнее здесь: https://stackoverflow.com/questions/789 ... -entity-ok