我遇到的情况是,我有两个不同的对象,这些对象大致相同,但它们有不同的API。
如果我可以对待它们,我可以使用一种方法来处理它们。
基本上,我需要使用for循环迭代。这两个对象具有不同的函数名称,用于获取大小并在每个对象内部重新获取最新结果:
CustomUnMutableObj1.getMySize() CustomUnMutableObj2.getTotal()
CustomUnMutableObj1.getlastresult() CustomUnMutableObj2.getlastvalue()
无论如何我可以为两者使用相同的for循环,没有一大堆笨拙的条件,并且代码对于对象类型是盲目的吗?
答案 0 :(得分:0)
如果您无法修改有问题的两个类,以便它们实现一个通用接口,您仍然可以通过编写一些“适配器类”来获得相同的效果:
interface CustomObjInterface {
int getSize();
int getLatestResult();
}
class CustomUnMutableObj1Adapter implements CustomObjInterface {
private CustomUnMutableObj1 wrapped;
public CustomUnMutableObj1Adapter(CustomUnMutableObj1 wrapped) {
this.wrapped = wrapped;
}
@Override int getSize() {return wrapped.getMySize();}
@Override int getLatestResult() {return wrapped.getTotal();}
}
// and a similar class for CustomUnMutableObj2
然后使用适配器而不是原始对象:
void doStuff(CustomObjInterface obj) {
// do stuff with obj here, using getSize and getLatestResult
}
// call it like this, for a CustomUnMutableObj1
// If you had a CustomUnMutableObj2, you'd use a CustomUnMutableObj2Adapter instead
doStuff(new CustomUnMutableObj1Adapter(obj));
答案 1 :(得分:0)
有些不清楚的地方:你说&#34;通过使用for循环进行迭代&#34;,是否意味着你的方法获得Collection<Obj1>
或Collection<Obj2>
,但不是一个Collection<Object>
,其中包含Obj1
和Obj2
? (我的答案基于上述假设)
恕我直言,使用适配器(如其他答案所示)对于上述情况可能不是一个好的选择,因为如果你传递List<Obj1>
,你必须构建一个List<CustomUnMutableObj1Adapter>
并传递给你常用的处理方法&#34;您仍然需要一堆代码来处理它,并且每次调用流程逻辑时,您将为每个元素创建一个适配器列表+一个适配器,这可能不是一个好主意
当然,解决的最佳方法是引入一个通用接口/超类来为这些操作提供有意义的概念。但是,如果它不是一个选择,您可能会看到以下内容对您有帮助。
减少样板代码的一种方法是使用类似于模板方法的东西(如果你熟悉Spring,那么有很多类似的模板就像这样)
e.g。 (伪代码,未编译)
interface ProcessInfoExtractor<T> {
int getSize(T entity);
String getLastValue(T entity);
}
以上界面将负责执行&#34; common&#34;对提供的对象进行操作。
然后按照以下方式制作处理方法:
void <T> process(Collection<? extends T> entities, ProcessInfoExtractor<T> infoExtractor) {
for (T entity : entites) {
System.out.println("size " + infoExtractor.getSize(entity)
+ " last value " + infoExtractor.getLastValue(entity));
}
}
所以当您需要通过List<Obj1>
进行迭代时,只需执行:
process(obj1List,
new ProcessInfoExtractor<Obj1> (
@Override
int getSize(Obj1 obj1) { return obj1.getMySize(); }
@Override
String getLastValue(Obj1 obj1) { return obj1.getLastResult(); }
));
(Obj2
的类似情况)
为了方便调用者,您可以制作两个内部调用上述process
方法的包装器方法,例如
void process(Collection<Obj1> obj1List) {
process(obj1List, obj1InfoExtractor); // assume extractor is stateless,
// you can create one and reuse it
};
void process(Collection<Obj2> obj2List) {
process(obj2List, obj2InfoExtractor); // assume extractor is stateless,
// you can create one and reuse it
};