使用java8的lambdas作为方法参数以避免冗余

使用java8的lambdas作为方法参数以避免冗余,java,lambda,java-8,Java,Lambda,Java 8,我有一个类,有很多这样的方法(非常简化): public Record[] getRecordForXXX(String username, String param1) throws MyException { User user = getUser(String username); // Always the same MyObject myObj = getMyObject(param1); // Always the same // Here is the o

我有一个类,有很多这样的方法(非常简化)

public Record[] getRecordForXXX(String username, String param1) throws MyException {
    User user = getUser(String username); // Always the same
    MyObject myObj = getMyObject(param1); // Always the same

    // Here is the only line of code, this is different in any of thoose methods
    Record[] recs = getRecords1(user, myObject); // or getRecords2(user, myObject) ...

    // Handle those records always the same ...
    handleRecords(recs); // Always the same
    return recs; // Always the same
}
是否有任何方法可以使用lambdas来避免冗余,如:

   public Record[] getRecord(String userName, String param1, XXX method) throws MyException {
        User user = getUser(String username); // Always the same
        MyObject myObj = getMyObject(param1); // Always the same

        // => Call the given 'method' using the parameters user and myObj and returning records

        // Handle those records always the same ...
        handleRecords(recs); // Always the same
        return recs;  // Always the same
   }
我知道,我可以使用某种接口(命令模式)来实现这一点,但我喜欢使用更具功能性的方法。。。蒂亚

public Record[]getRecordForXXX(字符串用户名、字符串参数1、双函数加载器)抛出MyException{
public Record[] getRecordForXXX(String username, String param1, BiFunction<User, MyObject, Record[]> loader) throws MyException {
    User user = getUser(String username); // Always the same
    MyObject myObj = getMyObject(param1); // Always the same

    Record[] recs = loader.apply(user, myObject);

    // Handle those records always the same ...
    handleRecords(recs); // Always the same
    return recs; // Always the same
}

getRecordForXXX("user", "param1", ClassName::getRecords1);
getRecordForXXX("user", "param1", ClassName::getRecords2);
User User=getUser(字符串用户名);//始终相同 MyObject myObj=getMyObject(参数1);//始终相同 记录[]recs=loader.apply(用户,myObject); //处理那些记录总是一样的。。。 HandlerRecords(recs);//始终不变 return recs;//始终相同 } getRecordForXXX(“用户”,“参数1”,类名::getRecords1); getRecordForXXX(“用户”,“参数1”,类名::getRecords2);
试试这个

public Record[] getRecord(String userName, String param1, BiFunction<User, MyObject, Record[]> method) throws MyException {
    User user = getUser(String username); // Always the same
    MyObject myObj = getMyObject(param1); // Always the same

    Record[] recs = method.apply(user, myObj);

    // Handle those records always the same ...
    handleRecords(recs); // Always the same
    return recs;  // Always the same
}

尽管lambdas在这里可能很有效,但您不会将其用于真正的用途。您正在寻找和枚举可以很好地实现策略模式

enum Type {

    XXX {

                @Override
                Record[] forType(User user, MyObject obj) {
                    // Something here.
                    return null;
                }
            },
    YYY {

                @Override
                Record[] forType(User user, MyObject obj) {
                    // Something here.
                    return null;
                }
            };

    abstract Record[] forType(User user, MyObject obj);
}

public Record[] getRecord(String userName, String param1, Type type) throws MyException {
    User user = getUser(userName); // Always the same
    MyObject myObj = getMyObject(param1); // Always the same

    // Use the Type to choose the strategy to grow the records.
    Recs recs = type.forType(user, myObj);

    // Handle those records always the same ...
    handleRecords(recs); // Always the same
    return recs;  // Always the same
}

调查方法参数将是
BiFunction
。这足够了吗?@ajb不幸的是,这还不够:我需要
QuadFunction)
。但是实现类似于
BiFunction
的接口应该不那么困难它们必须是静态的吗?@t777:对于非静态方法,您也可以使用
this::getRecords1
this::getRecords2
。@t777如果您有
User
getRecords1
方法,它接受一个
MyObject
参数并返回
Records[]
,您可以使用
User::getRecords1
。此外,您不必使用方法引用(语法
);您可以使用lambda作为第三个参数来
getRecordForXXX
。事实上,我有两个以上的参数。因此,我需要实现自己的
功能接口吗?最好编写自己的功能接口。假设参数的数量和类型是恒定的,这应该很简单。这是一个非常好的主意!如果这在(spring)事务上下文中有效,我必须进行评估。为什么您认为:“您不会使用它们[lambdas]来实现它们的真正用途”?@t777-为什么您认为…-因为lambda是简单策略之外的几个步骤——它们不仅提供了功能接口,还提供了类型安全性和本地参数封装以及各种其他好处。在这种情况下,他们是敲开螺母的大锤。当你遇到战略问题时,你应该使用战略解决方案。战略是行之有效的模式,不需要新的闪亮事物。当然,您可以在lambdas上以相同的方式实现,因为您需要指定一些通用接口,但不需要+1.这是我的解决方案
enum Type {

    XXX {

                @Override
                Record[] forType(User user, MyObject obj) {
                    // Something here.
                    return null;
                }
            },
    YYY {

                @Override
                Record[] forType(User user, MyObject obj) {
                    // Something here.
                    return null;
                }
            };

    abstract Record[] forType(User user, MyObject obj);
}

public Record[] getRecord(String userName, String param1, Type type) throws MyException {
    User user = getUser(userName); // Always the same
    MyObject myObj = getMyObject(param1); // Always the same

    // Use the Type to choose the strategy to grow the records.
    Recs recs = type.forType(user, myObj);

    // Handle those records always the same ...
    handleRecords(recs); // Always the same
    return recs;  // Always the same
}