我有几个扩展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
?还是泛型?
我正在使用这个构造来实现在运行时切换实现...
答案 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);
}