Search code examples
javadesign-patternsannotationsbuilder

How to mark a method obligatory?


Suppose you create a class names Person using the builder pattern, and suppose the Builder class contains methods body(), head(), arms() and of course build() and you consider methods head() and build() obligatory for the user of this class.

We would like to somehow mark these methods obligatory, if possible using annotations. If a user of this class tries to build a Person instance but forgot to call either of these methods, we would like to get some kind of warning - either from the java compiler, or maybe from Eclipse or Maven, which we use to build our projects - any of them would do.

Is it possible to do? Which way would you suggest?


Solution

  • Here is an example with using different types to make some parts mandatory (it also makes the order you call the methods mandatory):

    package test;
    
    import test.StepOne.StepThree;
    import test.StepOne.StepTwo;
    import test.StepOne.LastStep;
    
    public class TestBuilder {
    
        public static void main(String[] args) {
    
            String person1 = PersonBuilder.newInstance().head("head").body("body").arm("arm").leg("leg").build();
    
            String person2 = PersonBuilder.newInstance().head("head").body("body").arm("arm").build();
    
        }
    
    }
    
    interface StepOne {
    
        // mandatory
        StepTwo head(String head);
    
        interface StepTwo {
            // mandatory
            StepThree body(String body);
        }
    
        interface StepThree {
            // mandatory
            LastStep arm(String arm);
        }
    
        // all methods in this interface are not mandatory
        interface LastStep {
            LastStep leg(String leg);
            String build();
        }
    
    }
    
    class PersonBuilder implements StepOne, StepTwo, StepThree, LastStep {
    
        String head;
        String body;
        String arm;
        String leg;
    
        static StepOne newInstance() {
            return new PersonBuilder();
        }
    
        private PersonBuilder() {
        }
    
    
    
        public StepTwo head(String head) {
            this.head = head;
            return this;
        }
    
        public LastStep arm(String arm) {
            this.arm = arm;
            return this;
        }
    
        public StepThree body(String body) {
            this.body = body;
            return this;
        }
    
        public LastStep leg(String leg) {
            this.leg = leg;
            return this;
        }
    
        public String build() {
            return head + body + arm + leg;
        }
    }
    


    Edit

    The OP was so impressed with this answer that he wrote it up fully in a blog. It's such a clever take on the builder pattern that a full treatment deserves to be referenced here.