Создать абстрактную сущность для внешней библиотеки с реализацией в микросервисах (в микросервисах @Entity)
Подскажите, пожалуйста. Создаю внешнюю библиотеку в которой есть абстрактная фабрика
public abstract class GenerateFactory {
protected Map<Class<?>, Generate> generateMap = new HashMap<>();
public void register(Class<?> inputReportData, Generate generate) {
generateMap.put(inputReportData, generate);
}
public Generate createInstance(Class<? extends Object> inputReportData) {
return Optional.ofNullable(generateMap.get(inputReportData)).orElseThrow(NotSupportedGenerateException::new);
}
}
Данная фабрика создает в зависимости от переданного объекта Generate реализацию создания документа. В разных микросервисах требования к созданию документа разные.
А inputReportData (намеренно здесь написал Class<?>, чтобы подчеркнуть, что она должна быть абстрактной) в данный момент эта сущность представляет собой Enum, но общий Enum делать - не гуд, так как инкапсуляция нарушается).
public interface Generate<T> {
InputDataSetEnum getInputDataSet();
ReportPrintData convertToReportData(T dataSource);
@Autowired
default void registryGenerate(GenerateFactory factory) {
factory.register(getInputDataSet(), this);
}
}
В каждом микросервисе есть сущность ReportDataSetEntity
@Entity
@Table(name = "report_data_set")
public class ReportDataSetEntity {
@Id
@Column(name = "id", nullable = false)
private Long id;
@Column(name = "template_id", nullable = false, unique = true)
private String templateId;
@Column(name = "input_data_set")
@Enumerated(value = EnumType.STRING)
private InputDataSetEnum inputDataSetEnum;
//getter and setter
}
дак вот вопрос какой абстракцией описать ключ в protected Map<Class<?>, Generate> generateMap = new HashMap<>() ?
Или реализовывать свой Maр ?!
Ответы (1 шт):
Тут я предполагаю, что ключ в фабрике (inputReportData) - это тип отчета, и поле inputDataSetEnum уникально в таблице ReportDataSetEntity.
В библиотеке создайте понятия тип отчета, выраженное интерфейсом ReportType:
interface ReportType {
};
public abstract class GenerateFactory {
protected Map<ReportType, Generate> generateMap = new HashMap<>();
...}
В сервисах реализуйте этот интерфейс в enum:
public enum InputDataSetEnum implements ReportType {
...
}
Теперь без проблем можно регистрировать разные типы отчетов в фабрике, и нет глобального перечисления типа отчетов и библиотека о них не знает. О типах отчетов как и раньше знает только сервис.
Единственное что изменили, это то, что типы отчетов сервиса сделали типами отчетов, которые понимает фабрика (на своем абстрактом уровне, т.е. она умеет их только сравнивать).