web-dev-qa-db-ja.com

高次関数を受け入れるメソッドを持つジェネリックパラメーター化クラスを設計することは、Java 8で使用できる機能的手法ですか?

最近私はこの質問をしました: ジェネリックとファンクショナルを使用するコードをJava 8で記述し、オブジェクト指向のみを使用してoopとファンクショナルプログラミングを混合する)コードをどのように書き直しますか? stackoverflowで私は答えを得ることができませんでしたが、いくつかのコメントがあり、さらにこれは Inner Platform Effect であると述べています。

その後は、質問すべきだったのではないかと思ったので調査を続けたが、意味のある資料が見つからなかった。

これも私が尋ねているコードです(stackoverflowの質問にはクライアントコードもあります):

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

               //some logic here
                        MSGOUT callResult = queryFunc.apply(query);
               //another logic here
                        buffer = getResultList.apply(callResult);
               //yet another logic

               //return someThing;
            }
            //...    
}

私が尋ねようとしていたのは、それがなんらかのオブジェクト関数型プログラミングのデザインパターンであるか、そうでなければ、この手法の用語または名前があるのか​​ということです。

ここで私が注目している奇妙なケースは、通常、オブジェクト指向プログラミングのみを使用する場合、動的ディスパッチとポリモーフィズムを利用することで、いくつかの動作パラメータ化の選択肢(戦略パターン、テンプレートパターン、ビジターなど)があることです。関数型プログラミングに関しては、パターンマッチング、高次関数、構成があります。この場合、クラスのジェネリックスと高次関数である引数の型推論を利用することで、ある種のテンプレートまたは戦略パターンを実装しているように見えます。

より具体的には、クライアントはこのメソッドを呼び出して、入力と出力がそのようなものであるラムダ式を与えます。これらは、他の出力をinput(A, B, C型推論)をこれらのパラメーターに追加します。

         A query,             //param 1 => A
Function<A, B> queryFunc,     //param 2 => A -> B
Function<B, C> getResultList  //param 3 => B -> C

これはテクニックですか?その場合、その名前があり、Java 8で関数型プログラミングを利用していますか?この手法からほとんどの方法を得るにはどうすればよいですか?この手法を設計時により多くのパーツに適用できますか? Javaのプログラムは関数型プログラミングも利用していますか?


私の理解によれば、ここのコメントで示唆されているように、この抽象化の背後にある考えられる理由は(正しい用語の場合)です。

                               ==========================
consume other service     <-   Consumer Component         ->   consume a REST service to get all results page by page
                               ==========================
                                          |
                                          v
                    consume SOAP service to get all results page by page
                                ============================
                                e.g: SOAPConsumer
                                ----------------------------
                                private: offset = 0;
                                private: pageSize = 100;
                                private: filterCriteria = new FilterCriteria();
                                private: buffer = List.emptyList();
                                public: SOAPConsumer();
                                -----------------------------
                                public: consumeAll() {
                                  conn = connect();

                                  // I think it abstracts this while part. Maybe otherwise they thought that they need to implement that part in other consumers also.
                                  continue = true;
                                  while(continue) {   
                                      resultSet = sendRequest(conn, filterCriteria, offset, pageSize);
                                      resultSetWithMyInterestedPartOfTheResult = extract(resultSet);
                                      buffer.addAll(resultSetWithMyInterestedPartOfTheResult);
                                      lastResult = getLastResult(resultSet); //setNext
                                      offset = lastResult.getId();//setNext
                                      if(offset < pageSize) then continue = false;
                                  }
                                  return buffer;
                                }
                                private: connect();
                                private: sendRequest();
                                private: extract();
                                private: getLastResult()
                                private: setNext();
                                ---------------------------------

私が質問に書いているように、私は主にfpとoopを混合するときに一般的な手法であるかどうかを調査しています。

1

getSomethingメソッドと抽象クラスは同等です。どちらも戦略パターンの例です。

public abstract class SomethingGetter<R, MSGIN, MSGOUT> {
    abstract MSGOUT query(MSGIN in);
    abstract List<R> getResults(MSGOUT out);

    public SomeClass<R> run(MSGIN query) {
       //some logic here
                MSGOUT callResult = queryFunc.apply(query);
       //another logic here
                buffer = getResultList.apply(callResult);
       //yet another logic

       //return someThing;
    }
}

// logic heresには、R、MSGIN、またはMSGOUTに関連するものがあってはならないことに注意してください。何がで​​きるかについての制約がないためです。おそらくそれは、ロギングの例外やプロファイリングのようなデータに関係のないものです。

2
Caleth