简体   繁体   中英

Is there any design pattern for this? (Builder, Inheritance)

I have following structure:

public class MyClass {

    public static class DefaultBuilder {
        private int config1;
        private String config2;

        public DefaultBuilder configMethod1(int config1){
            this.config1 = config1;
            return this;
        }

        public DefaultBuilder configMethod2(String config2){
            this.config2 = config2;
            return this;
        }
    }

    public static class SpecialBuilder extends DefaultBuilder {
        private long specialConfig1;

        public SpecialBuilder specialConfigMethod1(long specialConfig1){
            this.specialConfig1 = specialConfig1;
            return this;
        }

    }
}

...

public class Main {

    public static void main(String[] args){
        new MyClass.DefaultBuilder().configMethod1(1).configMethod2("Test"); // Works great
        new MyClass.SpecialBuilder().specialConfigMethod1(10).configMethod1(1).configMethod2("Test"); // Works great
        new MyClass.SpecialBuilder().configMethod1(1).configMethod2("Test").specialConfigMethod1(10); // Does not work
    }
}

I only can use the specialConfigMehthod1 when using it as the first method. But because this should be an API for a library I don't want to tell the user how he has to order his call. Furthermore I don't want that the user can call specialConfigMethod1() when he is just using a DefaultBuilder . I could override every method in my SpecialBuilder but I don't like that solution because then the inheritance is senseless.I also have thought about Interfaces but have not found any good solution there. Is there any design pattern or anything extremely simple I did not thought about (in Java if possible :) ):

If you want to see this in a working example you can go here: GitHub This is my first open source library and I don't like the API the way it is.

I think that the best approach is to define first the interface Builder, with the methods configMethod1(), configMethod2() and specialConfigMethod():

public interface Builder {

        Builder configMethod1(int config1);

        Builder configMethod2(String config2);

        Builder specialConfigMethod1(long specialConfig1);

}

Then you can define an abstract class AbstractBuilder to define some default implementation of the methods in the interface. I think that looking at your question the best would be this:

public abstract class AbstractBuilder implements Builder{
        private int config1;
        private String config2;

        @Override
        public Builder configMethod1(int config1){
            this.config1 = config1;
            return this;
        }

        @Override
        public Builder configMethod2(String config2){
            this.config2 = config2;
            return this;
        }
    }

And finally you define you SpecialBuilder extending the AbsractBuilder:

public class SpecialBuilder extends AbstractBuilder {
        private long specialConfig1;

        @Override
        public Builder specialConfigMethod1(long specialConfig1){
            this.specialConfig1 = specialConfig1;
            return this;
        }

    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM