如何通过classtype委托构造函数的实例化?

时间:2015-04-02 08:16:40

标签: java generics java-8

我有几个扩展BaseClass的类。现在我想在DelegatorContext中静态定义一个活动类,每个对象的创建都应该基于活动上下文。

示例:

class BaseClass {
    String firstname, lastname;
}

class FirstClas extends BaseClass {}
class SndClass extends BaseClass {}

class DelegatorContext {
    public static BaseClass activeClass;
}

class Delegator {
    BaseClass create(String firstname, String lastname) {
        return DelegatorContext.activeClass instanceof FirstClass
          ? new FirstClass(firstname, lastname) : new SndClass(firstname, lastname);
    }
}

如果引入更多实体扩展BaseClass,该示例将获得更多样板。

我的问题是否有更好的模式?甚至可能使用Java8和Functions?还是泛型?

我正在使用这个构造来实现在运行时切换实现...

3 个答案:

答案 0 :(得分:3)

您可以使用类型参数设置DelegatorContext泛型,该类型参数是BaseClass的子类。

此外,activeClass不应为static,并且应引入额外的Class<T>成员来保存有关Class的{​​{1}}信息。

它将用于实例化正确的子类:

activeClass

有了这个,你可以这样做:

class DelegatorContext<T extends BaseClass> {
    private Class<T> clazz;

    public T activeClass;

    private DelegatorContext(Class<T> clazz) { 
         this.clazz = clazz;
    }

    public T createInstance(String firstname, String secondname) {
        activeClass = clazz.newInstance();
        activeClass.setFirstName(firstname);
        activeClass.setSecondName(secondname);
        return activeClass;
    }

    public static <T extends BaseClass> DelegatorContext<T> of(Class<T> clazz) {
        return new DelegatorContext<T>(clazz);
    }
}

答案 1 :(得分:3)

我想,你的意思是这样的:

interface BaseClassFactory {
    BaseClass create(String firstname, String lastname);
}
class DelegatorContext {
    public static BaseClassFactory active;
}

...

DelegatorContext.active=FirstClass::new;

...

DelegatorContext.active=SndClass::new;

要求所有子类都有一个具有相同签名的构造函数,与工厂接口的签名相匹配(有趣的是给this recent question一个例子)

你真的不需要其他工厂类,但为了完整性,它将是:

class Delegator {
    BaseClass create(String firstname, String lastname) {
        return DelegatorContext.active.create(firstname, lastname);
    }
}

答案 2 :(得分:2)

从我所看到的情况来看,你最好在这里使用枚举:

enum DelegatorContext {
    First {
        @Override
        BaseClass instantiate(String firstName, String lastName) {
            return new FirstClass(firstName, lastName);
        }
    },
    Second{
        @Override
        BaseClass instantiate(String firstName, String lastName) {
            return new SecondClass(firstName, lastName);
        }
    };

    static Context defaultContext;
    abstract BaseClass instantiate(String firstName, String lastName);
}