我如何缩短包含很多重复的代码?

问题描述 投票:0回答:2
if (voucher.getDestinationCity() != null) {
    Optional<City> destinationCity = cityRepository.findOneByCode(voucher.getDestinationCity().getCode());
    if (destinationCity.isEmpty()) {
        throw new RequestRejectedException(RequestRejectionReason.INVALID_DESTINATION_CITY_CODE);
    }
    voucherCreated.setDestinationCity(destinationCity.get());
} else {
    voucherCreated.setDestinationCity(null);
}
if (voucher.getLeavingCountry() != null) {
    Optional<Country> optionalLeavingCountry = countryRepository.findOneByCode(voucher.getLeavingCountry().getCode());
    if (optionalLeavingCountry.isEmpty()) {
        throw new RequestRejectedException(RequestRejectionReason.INVALID_LEAVING_COUNTRY_CODE);
    }
    voucherCreated.setLeavingCountry(optionalLeavingCountry.get());
} else {
    voucherCreated.setLeavingCountry(null);
}
if (voucher.getLeavingCity() != null) {
    Optional<City> optionalLeavingCity = cityRepository.findOneByCode(voucher.getLeavingCity().getCode());
    if (optionalLeavingCity.isEmpty()) {
        throw new RequestRejectedException(RequestRejectionReason.INVALID_LEAVING_CITY_CODE);
    }
    voucherCreated.setLeavingCity(optionalLeavingCity.get());
} else {
    voucherCreated.setLeavingCity(null);
}

[存在一个包含许多带有@JoinColumn(...)字段的实体。另外,您还必须检查国家,城市等代码的存在。请参阅上面的示例。

问题是这样的代码很多(> 50)。如何做得更好?

P.S。:voucherCreatedvoucher是实体。

由Spring Data使用。

java jpa orm spring-data dto
2个回答
0
投票

您可能希望进一步看一下Optionals。他们辞职了。我注意到您进行了空检查,但是之后无论如何都要使用Optionals。在该可选项中,您可以使用ifPresent引发异常,但是可选项具有针对该异常的方法(请注意:与ifPresent相比,您总是有更好的选择)。更好的是这样的:

Object destCity = Optional.ofNullable(voucher.getDestinationCity())
                .map(dc -> cityRepository.findOneByCode(dc.getCode()))
                .orElseThrow(new RequestRejectedException(RequestRejectionReason.INVALID_DESTINATION_CITY_CODE);)
        voucherCreated.setDestinationCity(destCity);

0
投票

您可以尝试将其重构为更通用的名称,因为check方法本身会不断重复。我的答案假设CityCountry将具有方法Place的共同父对象,我称为getCode()。我还假设您可以将存储库重写为通用内容。我的示例代码如下:

private void doSomething(Voucher voucher) {
    Voucher voucherCreated = createVoucher();

    voucherCreated.setDestinationCity(evaluateVoucher(voucher,
            Voucher::getDestinationCity, cityRepository, RequestRejectionReason.INVALID_DESTINATION_CITY_CODE));

    voucherCreated.setLeavingCountry(evaluateVoucher(voucher,
            Voucher::getLeavingCountry, countryRepository, RequestRejectionReason.INVALID_LEAVING_COUNTRY_CODE));

    voucherCreated.setLeavingCity(evaluateVoucher(voucher,
            Voucher::getLeavingCity, cityRepository, RequestRejectionReason.INVALID_LEAVING_CITY_CODE));

    // ...
}

private <T extends Place> T evaluateVoucher(
        Voucher voucher,
        Function<Voucher, T> fieldExtractor,
        Repository<T> repository,
        RequestRejectionReason reason) {

    final T field = fieldExtractor.apply(voucher);
    if (field != null) {
        return repository
                .findOneByCode(field.getCode())
                .orElseThrow(() -> new RequestRejectedException(reason));
    }
    return null;
}

您可以进一步重构以将数据类型映射到您的存储库,这样您就不需要将存储库本身传递给方法,而是通过从字段提取器获取的数据类型来确定它。

© www.soinside.com 2019 - 2024. All rights reserved.