我应该这样做吗?

时间:2010-12-11 20:19:53

标签: java guava

我才开始学习番石榴。所以我不知道最佳做法等。 这些是代码(它绑定一些类并按输入集合放入Order):

public ImmutableList<ModelBean> toBean(Collection<Shape> model) {
    return ImmutableList.copyOf(Collections2.transform(Ordering.from(new Comparator<Shape>() {
        @Override
        public int compare(Shape o1, Shape o2) {
            return 0; //here placed some one line logic
        }
    }).sortedCopy(model), new Function<Shape, ModelBean>() {
        final ModelBeanCreator binder = new ModelBeanCreator();

        @Override
        public ModelBean apply(Shape input) {
            return binder.createModelBean(input);
        }
    }));
}

那么,我应该在几个操作中将它分开吗?

UPD 它有什么作用? 它需要收集。 对它进行排序。 将每个对象映射到另一个对象。 创建新的ImmutableList并将其返回。

3 个答案:

答案 0 :(得分:5)

我认为在一次调用中组合多个操作通常是可以的(只是遗憾的是Java没有扩展方法使它更漂亮),但我建议你包含逻辑内联。使用匿名类,它会变得混乱。

相反,将谓词,排序,预测等声明为常量:

private static Function<Shape, ModelBean> MODEL_BEAN_PROJECTION =
    new Function<Shape, ModelBean>() {
    final ModelBeanCreator binder = new ModelBeanCreator();

    @Override
    public ModelBean apply(Shape input) {
        return binder.createModelBean(input);
    }
};

然后您可以稍后在方法调用中使用MODEL_BEAN_PROJECTION。这样你就可以获得实际上相当容易阅读的代码,尽管做了很多。

另一方面,使用局部变量来描述在转换的每个阶段到目前为止所获得的内容的选项也是有用的。通常值得尝试一些代码,并查看哪些代码更具可读性 - 并且也要问同事。还尝试了不同的空白选项 - 我发现使用空白的代码之间的可读性差异可能很大。

答案 1 :(得分:2)

正如Jon Skeet指出的那样,将匿名对象移动到常量或单独的声明可以使代码更具可读性。如果您在其他地方使用相同的匿名对象,它们可以在类级别作用域,但如果您真的想要阻止它们重用,您也可以将它们作为方法中的最终声明范围。

public ImmutableList<ModelBean> toBean(Collection<Shape> model) {
    // I pulled out the first anonymous class object into a method scoped
    // reference and gave it some meaningful name based on what it does.
    final Comparator<Shape> shapeComparator = new Comparator<Shape>() {
        @Override
        public int compare(Shape o1, Shape o2) {
            return 0; //here placed some one line logic
        };

    // Also pulled out the second anonymous object into a method scoped
    // reference with meaningful name.
    final Function<Shape, ModelBean> sortFunc = new Function<Shape, ModelBean>() {
        final ModelBeanCreator binder = new ModelBeanCreator();

        @Override
        public ModelBean apply(Shape input) {
            return binder.createModelBean(input);
        }
    }; 

    // Now the transformation is much simpler without much work.
    return ImmutableList.copyOf(Collections2.transform(Ordering.from( shapeComparator ).sortedCopy(model), sortFunc ));
}

答案 2 :(得分:1)

另一个问题是是否使用函数式编程结构,例如Collections2.transform()。相反,你可以说

ImmutableList.Builder<ModelBean> builder = ImmutableList.builder();
for (Shape shape : sortedShapes) {
  builder.add(binder.createModelBean(shape));
}
return builder.build();

当你想要制作一个单独的副本时,我更喜欢显式迭代,因为它更容易阅读和编写这样的代码。