我有一组类,所有这些类都需要以某种(单独)方式执行。
通常,我只需创建一个带有单个 doSomething()
方法的 DoSomethingInterface
,并让每个类以适合每个类需求的方式实现该方法。但是,在这种情况下我不能这样做,因为类定义是不可修改的(自动生成的)
因此,我认为我需要创建一组不同的类,每个类采用一个自动生成的类并对它们执行操作。因此,假设我有 2 个自动生成的类,Class1
和 Class2
,我将首先定义一个通用的 Operator
接口(interface):
public interface Operator <TYPE>{
public void doSomething(TYPE type);
}
然后为每个类实现其中一个
public class Class1Operator implements Operator<Class1>{
public void doSomething(Class1 type){
...
...
}
}
和
public class Class2Operator implements Operator<Class2>{
public void doSomething(Class2 type){
...
...
}
}
好的,到目前为止一切顺利。现在,鉴于我有一个 Class1
类型的对象,是否有任何方法可以获取其运算符而不诉诸:
public Operator getOperator(Object obj){
if(obj instanceof Class1){
return new Class1Operator();
}else if(obj instanceof Class2{
return new Class2Operator();
}
return null;
}
这对我来说似乎是不好的做法......
我能想到的唯一其他方法是创建运算符到类名称的映射,如下所示:
Map<Class, Operator> allOperators = new HashMap<Class, Operator>();
allOperators.put(Class1.class, new Class1Operator());
allOperators.put(Class2.class, new Class2Operator());
然后使用以下方法返回运算符:
public Operator getOperator(Object obj){
return allOperators.get(obj);
}
但这似乎不对(我不确定,将对象从其类中删除是否存在任何问题......)
关于这两种方法是否“正确”有什么意见吗?还是有更优雅的解决方案?
谢谢
最佳答案
您所实现的(逐类映射方法)是我在教授模式时谈到的 GoF 访问者模式的替代方案之一。即使在运行时,它也是高效且可扩展的。比 if/else if/else 硬连线方法好得多。
关闭类的唯一问题是实际实例是否实现子类型而不是您提到的类类型;那么查找 map 将不起作用。
如果您需要识别子类型,我建议您使用 Aaron 的方法(沿着父类(super class)链向上),但您可能还想查看已实现的接口(interface)。如果您只需要“精确的类匹配”,请保持 getOperator 简单。
请注意,getOperator 中有一个错误 - 它应该如下所示:
public Operator getOperator(Object obj){
return allOperators.get(obj.getClass());
}
还有一件事...将您的 map 隐藏在另一个类中并按如下方式管理它:
private Map<Class<?>, Operator<?>> map = new HashMap<Class<?>, Operator<?>>();
public <T> void register(Class<T> clazz, Operator<T> operator) {
map.put(clazz, operator);
}
这可以防止任何人注册无法针对其所针对的类起作用的运算符。 (您可能希望使用 Operator 作为参数来允许针对父类(super class)编写的运算符,但这可能不是必需的)
关于Java 设计问题 - 向固定类添加功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/970546/