javarecordgetterlaw-of-demeter

How to Solve Law of Demeter Violation in Java Records?


I am using the below record in my Quarkus application and at some point I need to access the requestId field, located in Statements nested record. I want to avoid using the getters provided by the nested records since this will invoke a Law of Demeter violation. I tried to add a fifth field named Statements in KYAAutoResponse record and then use a custom method to gain access to requestId automatically but this returns null.

I am a little confused on how could I bypass the violation. Can you help me?

public record KYAAutoResponse(
        DataTransFlowAccessOutputRecord dataTransFlowAccessOutputRecord
) {
    public record DataTransFlowAccessOutputRecord(
            Data data
    ) {
        public record Data(
                Document document
        ) {
            public record Document(
                    Statements statements
            ) {
                @JsonInclude(JsonInclude.Include.NON_NULL)
                public record Statements(
                        @JsonProperty("request-id") String requestId
                ) {}
            }
        }
    }
}

Solution

  • I made the decision to follow the below approach which I think it's the closest in solving my problem. I placed methods in each of the nested records that call the next one. This means that KYAAutoResponse object knows the internals of DataTransFlowAccessOutputRecord etc.

    public record GovResponse(
            DataTransFlowAccessOutputRecord dataTransFlowAccessOutputRecord
    ) {
    
        public String getRequestId() {
            return dataTransFlowAccessOutputRecord.getRequestId();
        }
    
        public record DataTransFlowAccessOutputRecord(
                Data data
        ) {
    
            public String getRequestId() {
                return data.getRequestId();
            }
    
            public record Data(
                    Document document
            ) {
    
                public String getRequestId() {
                    return document.getRequestId();
                }
    
                public record Document(
                        Statements statements
                ) {
    
                    public String getRequestId() {
                        return statements.requestId;
                    }
    
                    @JsonbNillable
                    public record Statements(
                            @JsonbProperty("request-id") String requestId
                    ) {}
                }
            }
        }
    }