Java:如何使用相同的代码处理2个不同的对象相同?

时间:2015-10-05 00:47:27

标签: java

我遇到的情况是,我有两个不同的对象,这些对象大致相同,但它们有不同的API。

如果我可以对待它们,我可以使用一种方法来处理它们。

基本上,我需要使用for循环迭代。这两个对象具有不同的函数名称,用于获取大小并在每个对象内部重新获取最新结果:

CustomUnMutableObj1.getMySize() CustomUnMutableObj2.getTotal()

CustomUnMutableObj1.getlastresult() CustomUnMutableObj2.getlastvalue()

无论如何我可以为两者使用相同的for循环,没有一大堆笨拙的条件,并且代码对于对象类型是盲目的吗?

2 个答案:

答案 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>,其中包含Obj1Obj2? (我的答案基于上述假设)

恕我直言,使用适配器(如其他答案所示)对于上述情况可能不是一个好的选择,因为如果你传递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
};