我想更新一個物件,但事先我檢查了可以更新的欄位;然后我將欄位的名稱收集到一個串列中。
我的問題是它有太多的 if 陳述句,我想減少它們。有什么好的方法嗎?
/**
* This method checks if there are any updates for a company
*
* @param company The data that comes from the database, and we want to update.
* @param companyDTO The data that may contain updates.
* @return The method returns with a list that contains the changes.
*/
private List<String> getChanges(Company company, CompanyDTO companyDTO) {
List<String> changes = new ArrayList<>();
if (companyDTO.getName() != null && !companyDTO.getName().equals(company.getName())) {
changes.add(COMPANY_NAME);
}
if (companyDTO.getShortName() != null && !companyDTO.getShortName().equals(company.getShortName())) {
changes.add(COMPANY_SHORTNAME);
}
if (companyDTO.getAddress() != null && !companyDTO.getAddress().equals(company.getAddress())) {
changes.add(COMPANY_ADDRESS);
}
if (companyDTO.getTaxNumber() != null && !companyDTO.getTaxNumber().equals(company.getTaxNumber())) {
changes.add(COMPANY_TAX_NUMBER);
}
if (companyDTO.getFirmId() != null && !companyDTO.getFirmId().equals(company.getFirmId())) {
changes.add(COMPANY_FIRM_ID);
}
if (companyDTO.getBankName() != null && !companyDTO.getBankName().equals(company.getBankName())) {
changes.add(COMPANY_BANK_NAME);
}
if (companyDTO.getBankAccountNumber() != null && !companyDTO.getBankAccountNumber().equals(company.getBankAccountNumber())) {
changes.add(COMPANY_BANK_ACCOUNT_NUMBER);
}
if (companyDTO.getInternalComment() != null && !companyDTO.getInternalComment().equals(company.getInternalComment())) {
changes.add(COMPANY_INTERNAL_COMMENT);
}
if (companyDTO.getEnabled() != null && !companyDTO.getEnabled().equals(company.getEnabled())) {
changes.add(ENABLED);
}
return changes;
}
uj5u.com熱心網友回復:
我看到兩種一般方法:
創建封裝 if 陳述句的不同部分的物件:
record ChangeCheck(Function<CompanyDTO, Object> dtoField, Function<Company, Object> entityField, Change change){ boolean check (CompanyDTO dto, Company entity){ return Objects.equals(dtoField.apply(dto), entityField.apply(company); } }然后,您可以創建此類物件的集合
List<ChangeCheck> checkers = new ArrayList<>(); checkers.add(new ChangeCheck(CompanyDTO::getBankName, Company::getBankName, COMPANY_BANK_NAME));在您的方法中,您只需迭代該集合。
for (ChangeCheck check : checkers){ if (check.check(companyDTO, company)) { changes.add(check.check); } }或者,您可以使用反射來查找 dto 的所有欄位、物體的匹配欄位和常量/列舉,以添加到您的更改集合中。
第一種方法易于實作和理解,但需要與 if 條件大致相同的輸入量。至少它確實消除了重復的邏輯。
uj5u.com熱心網友回復:
您可以提取那些將值獲取到(lambda)函式中的呼叫,然后使用這些函式的串列并迭代它們,大致就像
@Value // lombok to write the constructor, write out the class if you don't have that
static class Extractor {
final Function<CompanyDTO, Object> dtoValue;
final Function<Company, Object> value;
String name;
}
List<Extractor> extractors = Arrays.asList(
new Extractor(CompanyDTO::getA, Company::getA, "company.a"),
new Extractor(CompanyDTO::getB, Company::getB, "company.b")
);
private List<String> getChanges(Company company, CompanyDTO companyDTO) {
List<String> result = new ArrayList<>();
extractors.forEach(e -> {
Object old = e.value.apply(company);
Object updated = e.dtoValue.apply(companyDTO);
if (old != null && !old.equals(updated))
result.add(e.name);
});
return result;
}
@Value
static class CompanyDTO {
final String a;
final Date b;
}
@Value
static class Company {
final String a;
final Date b;
}
uj5u.com熱心網友回復:
您可以創建三個串列,其中一個是您要比較的物件,一個是您要比較的其他物件,第三個是所有常量:
private List<String> getChanges(Company company, CompanyDTO companyDTO) {
List<String> changes = new ArrayList<>();
Object[] first = [company.getName(), company.getCity(), company.getCountry() ...];
Object[] second = [companyDTO.getName(), companyDTO.getCity(), companyDTO.getCountry() ...];
String[] constants = [COMPANY_NAME, COMPANY_CITY, COMPANY_COUNTRY ...];
for (int i = 0; i < first.length; i ) {
if (first != null && !first[i].equals(second[i])) {
changes.add(constants[i]);
}
}
return changes;
}
uj5u.com熱心網友回復:
我會說在這里使用反射。
假設 Company 和 CompanyDTO 具有相同的欄位名稱。
private List<String> getChanges(final Company company, final CompanyDTO companyDTO) {
final List<String> result = new ArrayList<>();
for (final Field dtoField : CompanyDTO.class.getDeclaredFields()) {
ReflectionUtils.makeAccessible(dtoField);
for (final Field comField : Company.class.getDeclaredFields()) {
ReflectionUtils.makeAccessible(comField);
if (dtoField.getName().equals(comField.getName())) {
final Object dtoObject = ReflectionUtils.getField(dtoField, dto);
final Object companyObject = ReflectionUtils.getField(comField, com);
if (!Objects.equals(dtoObject, companyObject)) {
result.add(dtoField.getName());
}
}
}
}
return result;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/513981.html
