我有一个名为Base
的抽象类,它处理一堆逻辑来处理我拥有的一些数据。 API 如下所示:
// Class has no abstract methods, but is uninstantiable
public abstract class Base {
private Param param;
protected Base() {}
protected void setParam(Param param) {
this.param = param
}
public void doThing() {
// Code here to do a common thing
}
public void doOtherThing() {
// Code here to do another common thing
}
protected void handle(Object... objects) {
// This code delegates work to a scripting language via the param
// It is not type safe and the array of objects needed will vary depending
// on the implementing class.
}
}
当然,这里奇怪的是handle(Objects...)
方法。要展示它的使用方式,请查看其中一个子类:
public class Person extends Base {
protected Person(Param param) {
super();
setParam(param);
}
public void handle(String name, int age) {
// Expose a type safe interface to the world
super.handle(name, age);
}
}
正如您所看到的,子类隐藏了 super.handle
,它对于某些参数是 protected ,以便此类的使用者可以进行类型安全的交互,而无需传递对象数组。问题是,我想从一个强制每个参数有一个子类实例的工厂创建它们。目前,这个工厂看起来像这样:
public class Factory {
Map<Param, Person> persons;
Map<Param, Other> others; // Other also extends Base
public Person getPerson(Param param) {
Person person = persons.get(param);
if (person == null) {
person = new Person(param);
persons.put(param, person);
}
return person;
}
public Other getOther(Param param) {
Other other = others.get(param);
if (other == null) {
other = new Other(param);
other.put(param, other);
}
return other;
}
}
显然,这很糟糕,但我想不出更好的方法来处理这种情况,因为通过参数与脚本语言交互的奇怪性质,它依赖于字符串构造来执行代码。有人对如何清理这个设计有任何指导吗?
最佳答案
可以使用一些泛型和反射来概括工厂类,以便在运行时实例化特定的子类类型:
import java.util.HashMap;
import java.util.Map;
public class Factory<T> {
private Map<Param, T> instances = new HashMap<Param, T>();
public final T create(Class<T> clazz, Param param) throws Exception {
T cur = instances.get(param);
if (cur == null) {
cur = clazz.newInstance();
((Base)cur).setParam(param);
instances.put(param, cur);
}
return cur;
}
}
子类应该有无参数构造函数,而不是公共(public)的;为了保持一致性,删除 with-param 1:
public class Person extends Base {
protected Person(){}
public void handle(String name, int age) {
// Expose a type safe interface to the world
super.handle(name, age);
}
}
使用示例:
public class TestFactory {
public static void main(String[] args) throws Exception {
Factory<Person> factory = new Factory<Person>();
Person p = factory.create(Person.class, new Param());
}
}
当然,我知道这不是一种模式,也不是我可以引以为豪的更优雅的代码,但仍然避免了您必须为每个新子类更改工厂,它不使用静态方法并在单点中保留缓存逻辑。
关于java - 当您有一堆极其相似且无法共享接口(interface)的类时,应该使用什么正确的设计模式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22122045/