Реализовать шаблон проектирования посредника в приложении Spring REST? - PullRequest
0 голосов
/ 11 июня 2019

Я работаю в FHIR API.У меня есть интерфейс PatientService и 2 класса реализации, таких как DSTU2PatientService, STU3PatientService.

В нашем клиенте реализован API-интерфейс FHIR DSTU2 для демографии, тогда как процедура находится в STU3.

Мой пример использования: как определить, какая служба (DSTU2 / STU3) должна вызываться, когда от пациента поступает запрос на получение данных о состоянии его здоровья из системы EHR.

Как включить шаблон посредникавыполнить вызов динамически?Я не хочу использовать if условие.

application.properties

fhir.demogrphics=DSTU2
fhir.procedure=STU3

FHIRPatientService.java

public interface FHIRPatientService {

    Object getDemographics(PatientDTO patient);

    Object getProcedures(PatientDTO patient);
}

Я интегрировал FHIR DSTU2 API DSTU2PatientService.

DSTU2PatientService.java

@Service(value = "dstu2PatientService")
public class DSTU2PatientService implements PatientService {

    private static final Logger LOG = LoggerFactory.getLogger(DSTU2PatientService.class);

    private FhirContext fhirContextDstu2;

    @Autowired
    private FHIRConfig fhirConfig;

    @Autowired
    private BasicAuthInterceptor authInterceptor;

    public DSTU2PatientService(@Qualifier("fhirContextDstu2") FhirContext fhirContextDstu2) {
        this.fhirContextDstu2 = fhirContextDstu2;
    }

    @Override
    public Object getDemographics(PatientDTO patient) {
        Bundle bundle = null;
        try {
            IGenericClient clientDstu2 = fhirContextDstu2.newRestfulGenericClient(fhirConfig.getFhirServerPathDstu2());
            clientDstu2.registerInterceptor(authInterceptor);

            bundle = clientDstu2.search()
                .forResource(Patient.class)
                .where(Patient.GIVEN.matches().value(patient.getGiven()))
                .and(Patient.FAMILY.matches().value(patient.getFamily()))
                .and(Patient.BIRTHDATE.exactly().day(patient.getBirthdate()))
                .and(Patient.ADDRESS.contains().value(patient.getAddress()))
                .and(Patient.GENDER.exactly().codes(patient.getGender()))
                .returnBundle(Bundle.class)
                .execute();
        }catch(Exception e){
            LOG.error("Demographics: {}", e.getMessage());
            bundle = new Bundle();
        }
        return bundle;
    }

    @Override
    public Object getProcedures(PatientDTO patient) {
        Bundle bundle = null;
        try {
            IGenericClient clientDstu2 = fhirContextDstu2.newRestfulGenericClient(fhirConfig.getFhirServerPathDstu2());
            clientDstu2.registerInterceptor(authInterceptor);
            clientDstu2.registerInterceptor(CommonUtil.headersInterceptor(patient.getMychartId()));
            bundle = clientDstu2.search()
                    .forResource(Procedure.class)
                    .where(new ReferenceClientParam("patient").hasId(patient.getSubject()))
                    .and(Procedure.DATE.afterOrEquals().day(patient.getStartDate()))
                    .and(Procedure.DATE.beforeOrEquals().day(patient.getEndDate()))
                    .returnBundle(Bundle.class)
                    .execute();
        }catch(Exception e){
            LOG.error("Procedures: {}", e.getMessage());
            bundle = new Bundle();
        }
        return bundle;
    }
}

Я интегрировал FHIR STU3 API STU3PatientService.

STU3PatientService.java

@Service(value = "stu3PatientService")
public class STU3PatientService implements PatientService {

    private static final Logger LOG = LoggerFactory.getLogger(STU3PatientService.class);

    private FhirContext fhirContextStu3;

    @Autowired
    private FHIRConfig fhirConfig;

    @Autowired
    private BasicAuthInterceptor authInterceptor;

    public STU3PatientService(@Qualifier("fhirContextStu3") FhirContext fhirContextStu3) {
        this.fhirContextStu3 = fhirContextStu3;
    }

    @Override
    public Object getDemographics(PatientDTO patient) {
        Bundle bundle = null;
        try {
            IGenericClient clientStu3 = fhirContextStu3.newRestfulGenericClient(fhirConfig.getFhirServerPathStu3());
            clientStu3.registerInterceptor(authInterceptor);

            bundle = clientStu3.search()
                    .forResource(Patient.class)
                    .where(Patient.GIVEN.matches().value(patient.getGiven()))
                    .and(Patient.FAMILY.matches().value(patient.getFamily()))
                    .and(Patient.BIRTHDATE.exactly().day(patient.getBirthdate()))
                    .and(Patient.ADDRESS.contains().value(patient.getAddress()))
                    .and(Patient.GENDER.exactly().codes(patient.getGender()))
                    .returnBundle(Bundle.class)
                    .execute();
        }catch(Exception e){
            LOG.error("Demographics: {}", e.getMessage());
            bundle = new Bundle();
        }
        return bundle;
    }

    @Override
    public bundle getProcedures(PatientDTO patient) {
        Bundle bundle = null;
        try {
            IGenericClient clientStu3 = fhirContextStu3.newRestfulGenericClient(fhirConfig.getFhirServerPathStu3());
            clientStu3.registerInterceptor(authInterceptor);
            clientStu3.registerInterceptor(CommonUtil.headersInterceptor(patient.getMychartId()));

            bundle = clientStu3.search()
                    .forResource(Procedure.class)
                    .where(new ReferenceClientParam("patient").hasId(patient.getSubject()))
                    .and(Procedure.DATE.afterOrEquals().day(patient.getStartDate()))
                    .and(Procedure.DATE.beforeOrEquals().day(patient.getEndDate()))
                    .returnBundle(Bundle.class)
                    .execute();
        }catch(Exception e){
            LOG.error("Procedures: {}", e.getMessage());
            bundle = new Bundle();
        }
        return bundle;
    }

}

FHIRComponent.java

@Component(value = "fhirService")
public class FHIRComponent {

    private static final Logger LOG = LoggerFactory.getLogger(FHIRComponent.class);

    private FHIRResourceVersionConfig fhirResourceVersionConfig;
    private PatientService dstu2PatientService;
    private PatientService stu3PatientService;

    public FHIRComponent(
            @Qualifier("dstu2PatientService") FHIRPatientService dstu2PatientService,
            @Qualifier("stu3PatientService") FHIRPatientService stu3PatientService,
            FHIRResourceVersionConfig fhirResourceVersionConfig) {
        this.dstu2PatientService = dstu2PatientService;
        this.stu3PatientService = stu3PatientService;
        this.fhirResourceVersionConfig = fhirResourceVersionConfig;
    }

    public Object getDemographics(PatientDTO patient, String resourceType) {
        Object result = null;

        if("DSTU2".equalsIgnoreCase(fhirResourceVersionConfig.findResource(resourceName)))
            result = patientServiceDstu2.getDemographics(patient);
        else
            result = patientServiceStu3.getDemographics(patient);
        return result;
    }

    public Object getConditions(PatientDTO patient) {
        Object result = null;

        if("DSTU2".equalsIgnoreCase(fhirResourceVersionConfig.findResource(resourceName)))
            result = patientServiceDstu2.getConditions(patient);
        else
            result = patientServiceStu3.getConditions(patient);
        return result;
    }
}

1 Ответ

1 голос
/ 26 июня 2019

Вам необходимо сообщить FHIRPatientService, за какой код он отвечает:

public interface FHIRPatientService {

   String getCode();

   Object getDemographics(PatientDTO patient);

   Object getProcedures(PatientDTO patient);
}

Затем вы можете выполнить рефакторинг вашего компонента

@Component(value = "fhirService")
public class FHIRComponent {

    private static final Logger LOG = LoggerFactory.getLogger(FHIRComponent.class);

    private FHIRResourceVersionConfig fhirResourceVersionConfig;
    private List<PatientService> patientServices;//spring will inject all services

    public FHIRComponent(
        List<PatientService> patientServices,
        FHIRResourceVersionConfig fhirResourceVersionConfig) {
        this.patientServices= patientServices;
        this.fhirResourceVersionConfig = fhirResourceVersionConfig;
    }

    private Optional<PatientService> getService(String resourceType){
        return patientServices.stream()
            .filter(service => service.getCode().equalsIgnoreCase(fhirResourceVersionConfig.findResource(resourceName)))
            .findAny() 
    }

    public Object getDemographics(PatientDTO patient, String resourceType) {
        return getService(resourceType)
            .map(service => service.getDemographics(patient))
            .orElse(null);
   }
  ...

Надеюсь, мои объяснения немного ясны ...

...