如何使用lambda表达式重构工厂类?

时间:2015-03-23 14:57:35

标签: java lambda java-8

一个常见的用例是定义某种工厂类:

public abstract class IFactory {
    public abstract Object getObject(String input);
}

实现工厂应该根据input提供对象。

例如:

public class FactoryImpl {
    private static instance = null;

    public IFactory instance() {
        if (instance == null) {
            return new IFactory() {
                @Override
                public Object getObject(String input) {
                    return new Object(); //based on input data in real 
                }
            };
        }
    }
}

这很麻烦,所以我想使用lambda表达式重构代码。 但是首选方式是什么?

我可以想象以下两种选择:

public class FactoryImpl {
    public IFactory instance() {
        if (instance == null) {
            return (data) -> new Object(); //explicit using new operator
        }
    }
}

public class FactoryImpl {
    public IFactory instance() {
        if (instance == null) {
            IFactory factory = Object::new;
            return (data) -> factory.getObject(); //using method reference
        }
    }
}

是否有一种应该首选的方法(例如,对于可读性或惯例)?

1 个答案:

答案 0 :(得分:2)

你正在使你的生活变得多么复杂。

如果您有interface之类的

public interface IFactory {
    Object getObject(String input);
}

您可以将其实现为

public class NameIsIrrelevant {
    public IFactory instance() {
        return input -> new Object();
    }
}

没有考虑单身人士模式。虽然不能保证,但是实现 会在这里返回单例实现,就像它一直用于非捕获lambdas一样。

这不是铁硬的保证,但另一方面,如果返回的实例不是单身人士,则没有任何伤害......


这与您是否将使用lambda表达式或方法引用的问题无关。

如果你的工厂应该构造的类型有一个接受工厂输入作为参数值的构造函数,你可以将工厂实现为

public class NameIsIrrelevant {
    public IFactory instance() {
        return TheType::new;
    }
}

但这只是一个小小的优化,或者说是一种风格选择;它不会以任何方式改变工厂的工作方式。如果没有这样的构造函数,那么无论如何都没有必要尝试使用方法引用。