使用反射的通用Builder模式类

时间:2014-09-18 10:03:01

标签: java generics reflection builder-pattern

使用泛型实现构建器模式会很棒。从理论上讲,可以使用反射来实现以下目标:

    MyClass myClass = GenericBuilder<MyClass>.aObject()
            .withThisProperty("foo")
            .withThatProperty(4)
            .build();

我已经制作了以下代码:

    public class CursistBuilder {
        private Cursist cursist = null;

        private CursistBuilder() {
            cursist = new Cursist("username not set", "email not set");
        }

        public static CursistBuilder aCursist() {
            return new CursistBuilder();
        }

        public CursistBuilder withNaam(String name) {
            cursist.setGebruikersnaam(name);
            return this;
        }

        public CursistBuilder withEmail(String email) {
            cursist.setEmail(email);
            return this;
        }

        public Cursist build() {
            return cursist;
        }
    }

如何实现这一目标?

2 个答案:

答案 0 :(得分:2)

它不是正确的构建器模式,因为对象不是在create函数中创建的,但您可以将其用作改进的参考

public static class Builder<T> {
        public final T instance;

        public Builder(Class<T> clazz) throws InstantiationException,
                IllegalAccessException {
            super();
            this.clazz = clazz;
            this.instance = clazz.newInstance();
        }

        private final Class<?> clazz;

        Builder<T> setProperty(String name, Object value)
                throws IllegalAccessException, IllegalArgumentException,
                InvocationTargetException, NoSuchMethodException,
                SecurityException {

            Method method = clazz.getMethod("set"
                    + name.substring(0, 1).toUpperCase() + name.substring(1),
                    value.getClass());
            method.invoke(instance, value);
            return this;
        }

        T create() {
            return instance;
        }
    }

如何使用它: 你通过将类传递给构造函数

来创建构建器的实例

Builder<MyClass> builder = new Builder<>(MyClass.class);

然后使用方法setProperty(String name, Object value)来调用对象上的setter,

你做了什么?例如,为您的类传递一些默认值,不要使用非args构造函数

答案 1 :(得分:0)

我不知道这是你想要的,但如果我是你,我将按照以下方式实施//

main&gt;&gt;

public class Main {
    public static void main(String[] args) {
        GenericBuilder gb = GenericBuilder.getInstance();
        gb=
        gb.withThisProperty("String", "AAAAAA").
        withThisProperty(4, 9).
        withThisProperty(5.8f, 6.7f).
        withThisProperty("Array", new ArrayList<String>()).build();

        System.out.println(gb.toString());
    }
};

VO&gt;&gt;

public class GenericBuilder {

    private Map<Object, Object> map;

    // Implementation of Singleton 
    private GenericBuilder (){
        map = new HashMap<Object, Object>();
    }

    private static class LazyLoader{
        private static final GenericBuilder INSTANCE = new GenericBuilder(); 
    }

    public static GenericBuilder getInstance(){
        return LazyLoader.INSTANCE;
    }
    //End Singleton

    public GenericBuilder withThisProperty(Object key, Object param){
        map.put(key, param);
        return this;
    }

    public Object get(Object key){
        return map.get(key);
    }

    public GenericBuilder build(){
        return this;
    }

    @Override
    public String toString() {
        StringBuffer returnVal = new StringBuffer();
        Iterator<Object> iter = map.keySet().iterator();
        while(iter.hasNext()){
            Object key = iter.next();
            returnVal.append("key >> " + key  + " value >> " + map.get(key) + "\n");
        }
        return returnVal.toString();
    }
}

我重写toString()以显示其中的内容,并声明Map以将值分配给某个地方,如果您希望可以使用其他集合更改此值。感谢/