Этап 1: Анализ кода и рефакторинг
Задача: Проанализировать представленный Java-код и предложить варианты рефакторинга, направленные на улучшение его структуры, читаемости, поддерживаемости и тестируемости.
public class AutoUpdateByPermissionsServiceImpl implements AutoUpdateByPermissionsService, InitializingBean {
private static final Logger logger = LoggerFactory.getLogger(AutoUpdateByPermissionsServiceImpl.class);
private static final String ID_DOC_SCOPE_NAME = "id_doc";
private static final String TLS_DOC_SCOPE_NAME = "tls_doc";
private static final String INN_SCOPE_NAME = "inn";
private static final String PENSION_REFERENCE_SCOPE_NAME = "pension_reference";
private static final String NOFL_PERSON_SCOPE_NAME = "nofl_person";
private static final String ELECTRONIC_WORKBOOK_SCOPE_NAME = "electronic_workbook";
private static final String PRE_RETIREMENT_AGE_SCOPE_NAME = "pre_retirement_age";
private static final String MEDICAL_DOC_SCOPE_NAME = "medical_doc";
private static final String FAMILY_ASSETS_BALANCE_SCOPE_NAME = "family_assets_balance";
private static final String PAYMENTS_EGSSO_SCOPE_NAME = "payments_egsso";
private static final String DISABLED_PERSON_SCOPE_NAME = "disabled_person";
private static final String KID_MEDICAL_DOC_SCOPE_NAME = "kid_medical_doc";
private static final String VEHICLE_INFO_SCOPE_NAME = "vehicle_reg_cert_doc";
private static final String PAYOUT_INCOME_SCOPE_NAME = "payout_income";
private static final String EGE_RESULT_SCOPE_NAME = "ege_result";
private static final String EDUC_DOC_SCOPE_NAME = "educational_doc";
private static final String DRIVERS_LICENCE_DOC_SCOPE_NAME = "drivers_licence_doc";
private static final String ADD_EDUC_CERT_SCOPE_NAME = "add_educ_cert";
private final PersonEntityService personEntityService;
private final PersonInnService personInnService;
private final RequestBuilderService requestBuilderService;
private final DocumentEntityService documentEntityService;
private final DigitalDocumentService digitalDocumentService;
private final RPRequestService rpRequestService;
private final DBConfigService dbConfigService;
private final KidEntityService kidEntityService;
private final String pensionReferenceTerritorialOrganCode;
private final String pensionReferenceTerritorialOrganName;
private final String pensionReferenceMedicalUnchecked;
private List<String> autoUpdatePermissionScopes;
@Value("${http://esia.mvd.ru/digital}")
private String digitalHostWithContextUrl;
@Override
public void update(Long personId, List<String> scopes, String usi, String environment, String system, String subjectOid) {
scopes.retainAll(autoUpdatePermissionScopes);
logger.debug("Auto update by permissions started for person {}. Scopes: {}",
personId, CollectionUtil.prettyPrint(scopes));
if (CollectionUtils.isNotEmpty(scopes)) {
PersonEntity personEntity = personEntityService.findByPersonId(personId);
if (personEntity == null) {
logger.error("Person not found by id {}", personId);
return;
}
if (StringUtils.isBlank(personEntity.getSnils())) {
logger.error("Person with id {} hasn't snils", personId);
return;
}
AccessToken token = ContextHolder.getProperty(ESIAContext.ACCESS_TOKEN_PROPERTY_NAME);
if (scopes.contains(TLS_DOC_SCOPE_NAME)) {
tryCatchLog(() -> updateTlsDoc(personEntity, usi, environment, token), TLS_DOC_SCOPE_NAME);
}
if (scopes.contains(INN_SCOPE_NAME)) {
updateInn(personEntity, usi, environment);
}
if (scopes.contains(ID_DOC_SCOPE_NAME)) {
tryCatchLog(() -> updateIdDoc(personEntity, usi, environment, system, subjectOid), ID_DOC_SCOPE_NAME);
}
if (scopes.contains(PENSION_REFERENCE_SCOPE_NAME)) {
// ... (аналогичные блоки для других типов документов)
}
if (scopes.contains(EDUC_DOC_SCOPE_NAME)) {
tryCatchLog(() -> updateEducDoc(personEntity, usi, environment, token), EDUC_DOC_SCOPE_NAME);
}
if (scopes.contains(DRIVERS_LICENCE_DOC_SCOPE_NAME)) {
tryCatchLog(() -> updateGisddDriverLicense(personEntity.getId()), DRIVERS_LICENCE_DOC_SCOPE_NAME);
}
if (scopes.contains(EmbeddedScopeEnum.VEHICLE_SELF_PROPELLED_DOC.name())) {
tryCatchLog(() -> updateVehicleSelfPropelled(personEntity.getId()), EmbeddedScopeEnum.VEHICLE_SELF_PROPELLED_DOC.name());
}
if (scopes.contains(EmbeddedScopeEnum.SELF_EMPLOYED.name())) {
tryCatchLog(() -> updateSelfEmployedIncome(personEntity.getId()), EmbeddedScopeEnum.SELF_EMPLOYED.name());
}
if (scopes.contains(ADD_EDUC_CERT_SCOPE_NAME)) {
tryCatchLog(() -> updateAddEducCert(personEntity, usi, environment, token), ADD_EDUC_CERT_SCOPE_NAME);
}
} else {
logger.error("Can't process auto update for person #{}. Permission scopes are empty after retain. Allowed scopes: {}",
personId, CollectionUtil.prettyPrint(autoUpdatePermissionScopes));
}
}
private void updateAddEducCert(PersonEntity personEntity, String usi, String environment, AccessToken token) {
boolean autoUpdateEnabled = dbConfigService.getBooleanProperty("check.permission.on.add.educ.doc", false);
if (!autoUpdateEnabled) {
logger.info("Auto update by permission disabled for add_educ_cert");
return;
} else {
List<KidEntity> kids = kidEntityService.findByParentId(personEntity.getId());
for (KidEntity kid : kids) {
try {
digitalDocumentService.createAddEducCertRequest(personEntity, kid.getId(), usi, environment, token);
} catch (Exception e) {
logger.error("Error create add educ cert for kid {}: ", kid.getId(), e);
}
}
}
}
private void tryCatchLog(Runnable runnable, String scope) {
try {
runnable.run();
} catch (Exception e) {
logger.error("Can't update by permission scope {}: ", scope, e);
}
}
Вопросы для обсуждения:
- Какие проблемы вы видите в представленном Java-коде?
- Как бы вы рефакторили метод
updateв классеAutoUpdateByPermissionsServiceImpl? - Предложите способы уменьшения дублирования кода и улучшения читаемости.
- Как можно улучшить структуру констант (например,
ID_DOC_SCOPE_NAME)? - Как бы вы улучшили обработку ошибок и логирование в данном коде?
- Как можно повысить тестируемость данного кода?
Вложения




