Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
255 views
in Technique[技术] by (71.8m points)

java - Is there a way to simplify a code with a repeating if-then pattern?

I have created a basic CRUD API using Spring Boot , in that I have created a service class for my controller.

The following is my service method of the Controller.

Services

public Customer updateCustomer(Customer newCustomer, Long customerId) throws ResourceNotFoundException {
        
        return customerRepo.findById(customerId)
                .map(customer -> {
                    if (newCustomer.getName() != null)
                        customer.setName(newCustomer.getName());
                    if (newCustomer.getGstin() != null)
                        customer.setGstin(newCustomer.getGstin());
                    if (newCustomer.getPhoneNumber() != null)
                        customer.setPhoneNumber(newCustomer.getPhoneNumber());
                    if (newCustomer.getAddress() != null)
                        customer.setAddress(newCustomer.getAddress());
                    if (newCustomer.getOutstandingBalance() != 0.0f)
                        customer.setOutstandingBalance(newCustomer.getOutstandingBalance());
                    return customerRepo.save(customer);
                }).orElseThrow(() -> new ResourceNotFoundException());

    }

My question is: Is it possible to simplify the code which is Using multiple if?

If there is, can anyone suggest a simplification to handle this logic..??


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Yet another approach of doing that might look like this.

I would love if Java supported in-language macros so that such patterns might be wrapped in a macro call and then expanded to generated source code. Having no macros, that all can be put in methods and do the check-copy pattern at runtime:

public final class Patch {

    private Patch() {
    }

    public static <T> void nonNull(final Supplier<? extends T> get, final Consumer<? super T> set) {
        @Nullable
        final T value = get.get();
        if ( value != null ) {
            set.accept(value);
        }
    }

    public static void nonZero(final DoubleSupplier get, final DoubleConsumer set) {
        final double value = get.getAsDouble();
        if ( value != 0 ) {
            set.accept(value);
        }
    }

}

Test:

@Data
@AllArgsConstructor
final class Customer {

    private final String name;
    private String phoneNumber;
    private float outstandingBalance;

}

And the test:

@Test
public void test() {
    final Customer customer = new Customer(null, "+123", 2);
    final Customer newCustomer = new Customer("john-doe", null, 0);
    Patch.nonNull(customer::getName, newCustomer::setName);
    Patch.nonNull(customer::getPhoneNumber, newCustomer::setPhoneNumber);
    Patch.nonZero(customer::getOutstandingBalance, value -> newCustomer.setOutstandingBalance((float) value));
    Assertions.assertEquals(new Customer("john-doe", "+123", 2), newCustomer);
}

Note that tools like Lombok generate Java code at compile time, but being javac plugins (see the @Data and AllArgsConstructor annotations) are black boxes that generate code themselves (equals(), hashCode(), toString(), get***() and set***() methods + the all-args constructor for Customer respectively) limiting to their current features only (+ requires IDE support to make it look nicer).

If you prefer Java Reflection that (may have) has higher runtime cost, take a look at Apache Commons BeanUtils that seem to do that job at runtime: Helper in order to copy non null properties from object to another


By the way, don't use float for outstandingBalance -- use BigDecimal or whatever precise. Why not use Double or Float to represent currency?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...