Lombok’s @Delegate comes in very handy when you want to use this programming pattern. Let’s consider an example:

  • We want Users and Customers to share some common attributes for naming and phone number
  • We define both an interface and an adapter class for these fields
  • We’ll have our models implement the interface and @Delegate to their adapter, effectively composing them with our contact information

1 - Define Interface and Adaptor as Support Class

public interface HasContactInformation {

    String getFirstName();
    void setFirstName(String firstName);
    String getFullName();
    String getLastName();
    void setLastName(String lastName);

    @Data
    @Builder
    @NoArgsConstructor
    @AllArgsConstructor
    class ContactInformationSupport implements HasContactInformation {

        private String firstName;
        private String lastName;

        @Override
        public String getFullName() {
            return getFirstName() + " " + getLastName();
        }
    }
}

2 - Utilizing in Both User.java and Customer.java Class

public class User implements HasContactInformation {
    @Delegate(types = {HasContactInformation.class})
    private ContactInformationSupport contactInformation = new ContactInformationSupport();
}

// With Builder
@Data
@Builder(toBuilder = true)
@AllArgsConstructor
@NoArgsConstructor
public class Customer implements HasContactInformation {
    @Delegate(types = {HasContactInformation.class})
    private ContactInformationSupport contactInformation = new ContactInformationSupport();

    public static Customer.CustomerBuilder builder() {
        return new Customer().toBuilder();
    }

    public static class CustomerBuilder {

        public Customer.CustomerBuilder firstName(String firstName) {
            if (this.contactInformation == null) this.contactInformation = new ContactInformationSupport();
            this.contactInformation.setFirstName(firstName);
            return this;
        }

        public Customer.CustomerBuilder lastName(String lastName) {
            if (this.contactInformation == null) this.contactInformation = new ContactInformationSupport();
            this.contactInformation.setLastName(lastName);
            return this;
        }
    }
}