您如何重写在 Java 8 中使用泛型和函数并仅使用面向对象的混合 oop 和函数式编程的代码?

Tah*_*dur 5 java generics functional-programming software-design java-8

我遇到过这种设计,但我没有完全掌握在 Java 8 中混合面向对象编程和函数式编程。

我对混合两种语言范式很感兴趣,而且互联网上的大多数教程都很简单,所以我无法通过混合来找到有关大规模软件设计的示例。所以有了这个示例案例,我想我有机会挖掘它的某些案例。

在这种情况下,让我展示代码的相关部分。这段代码包含一个通用的 FetchUtils 类,它实现了一个自定义迭代器,但为了简洁起见,我删除了一些部分。

public class FetchUtils<R, MSGIN, MSGOUT> {
    public SomeClass<R> getSomething(MSGIN query,
                                Function<MSGIN, MSGOUT> queryFunc,
                                Function<MSGOUT, List<R>> getResultList) {

               //...
                        MSGOUT callResult = queryFunc.apply(query);
                        buffer = getResultList.apply(callResult);
               //...
               //return someThing;
            }
            //...    
}
Run Code Online (Sandbox Code Playgroud)

在客户端中定义了一个函数和一个指向getCustomer类方法引用的 lambda 表达式。从客户端到使用泛型类型的上述方法的实际调用正在发送这些功能。

public class CustomerResponse {
   //...
   public List<Customer> getCustomer() {
        if (thing == null) {
            thing = new ArrayList<Customer>();
        }
        return this.customers;
    }
   //...
}

public class MyClient {

   //...

   @Autowired
   private FetchUtils<Customer, CustomerRequest, CustomerResponse> fetchUtils;

   //...

   public SomeClass<Customer> fetch() {

      //...

      Function<CustomerRequest, CustomerResponse> requestFunc = q -> {
            try {
                return myService.doSomething(q);
            } catch (Exception ex) {
                throw new RuntimeException(ex);
            }
        };

      CustomerRequest query = new CustomerRequest(/*...*/);

      return fetchUtils.getSomething(query,
                                     requestFunc,
                                     r -> r.getCustomer());

      //...
   }
   //...
}
Run Code Online (Sandbox Code Playgroud)

您如何仅使用面向对象的编程即不传递高阶函数并且仅使用动态分派甚至不使用泛型来重写此代码?

如果没有泛型,这种设计是否可行?

类型推断如何与这些泛型类型和函数一起工作?

这个设计是混合函数式和面向对象编程的一个可能的例子,或者你如何评估这个设计?

Jea*_*nès 6

您如何仅使用面向对象的编程即不传递高阶函数并且仅使用动态分派甚至不使用泛型来重写此代码?

class FuncImpl implements Function<CustomerRequest, CustomerResponse> {
    public CustomerResponse apply(CustomerResquest q) {
        try {
            return myService.doSomething(q);
        } catch (Exception ex) {
            throw new RuntimeException(ex);
        }
    }
}
Function<CustomerRequest, CustomerResponse> requestFunc = new FuncImpl();

class FuncImpl2 implements Function<CustomerResponse,List<Customer>> {
    public List<Customer> apply(CustomerResponse r) {
        return r.getCustomer();
    }
}

...
return fetchUtils.getSomething(query, requestFunc,new FuncImpl2());
Run Code Online (Sandbox Code Playgroud)

如果没有泛型,这种设计是否可行?

当然,在任何地方强制执行具体类型。(请参阅下面的类型推断并手工制作......)。

类型推断如何与这些泛型类型和函数一起工作?

泛型参数只是类型变量,所以你的例子很容易理解。

requestFun有类型Function<CustomerRequest, CustomerResponse>那么编译器可以很容易地推断出MSGINCustomerRequestand MSGOUT CustomerResponse

因为r -> r.getCustomer()编译器已经知道那MSGOUTCustomerResponse然后它查看CustomerResponse类型并发现getCustomer返回 aList<Customer>因此 lambda 有类型Function<CustomerResponse,List<Customer>>然后RList<Customer>

这个设计是混合函数式和面向对象编程的一个可能的例子,或者你如何评估这个设计?

是的,这是一个很好的例子。