3

Simulatorと呼ばれる単純なクラスを開発していましたが、これは特定の入力にSimulationのリストを適用します。各入力に対して、シミュレーションは、各シミュレーションに関して入力が満たさなければならないいくつかの条件に基づいて、出力を生成するか否かを生成することができる。 Simulatorによって生成される結果は、出力のリストです。情報隠蔽と関数プログラミングのコーディングスタイル

ここにコードがあります。あなたが見ることができるように、入力がSimulationで処理可能である場合

class Simulator { 
    final List<Simulation> simulations; 

    // Some initialization code... 

    List<Ouput> execute(Input input) { 
     return simulations 
      .stream() 
      .filter(s -> s.processable(input)) 
      .map(s -> s.prepareOutput(input)) 
      .collect(Collectors.toList()); 
    } 
} 

、最初私はそれがされていないため、シミュレーションをフィルタリングして、入力にこれらのシミュレーションを適用し、確認してください。

オブジェクト指向の観点からは、Simulationクラスの内部を公開しています。 processableメソッドで行われたチェック操作は、prepareOutputメソッド内に隠れているはずです。

Simulatorにはprocessableが表示されていますが、私はより機能的なアプローチを適用でき、非常に便利です。

どのアプローチが良いですか?私は行方不明の他の解決策はありますか?

Optional<Output> prepareOutput(Input input) { 

     boolean isProcessable = processable(input); // processable is private 

     if(isProcessable){ 
      // prepare Output 
      return Optional.of(Output); 
     } 
     return Optional.empty(); 

} 

そして、このような何か:あなたはprocessableを非表示にする必要がある場合は

+2

あなたが内部を公開していると思うなら、なぜそれをやるのですか?他のいくつかの質問について: 'someSimulation.prepareOutput(null)'を使ってシミュレーションを呼び出すとどうなりますか?それは処理可能なのでしょうか?または、私が 'prepareOutput'を、与えられたシミュレーションによって処理できない入力パラメータで呼び出すとどうなりますか?外部から加工性を知る必要がありますか?それは 'null'を返すのか、それとも例外をスローしますか? 'Optional'はオプションですか? – Roland

答えて

4

クラスSimulationが既に運転prepareOutputを露出しているために、これは失敗する可能性があります。processableメソッドを提供して、事前に検出すると、prepareOutput操作が失敗するかどうかを確認する必要はありません。実際には、あらかじめ計算するのが高価でない限り、そのようなチェックを提供するのは良いAPI設計です。

Simulationクラス内に一括処理操作を提供することも考えられます。

public class Simulation { 
    public Output prepareOutput(Input input) { 
     … 
    } 
    public static List<Output> prepareWhenPossible(List<Simulation> list, Input input) { 
     return simulations.stream() 
      .filter(s -> s.processable(input)) 
      .map(s -> s.prepareOutput(input)) 
      .collect(Collectors.toList()); 
    } 
} 

それは代わりに「オール・オア・ナッシング」動作を実装するので、操作が不可能であるための要素をスキップします呼び出し元にそれを明確にすることが重要です。

実装するのが安ければ、processableが公開されることはありません。まるでprepareOutputを呼び出して結果をドロップして、操作が可能かどうかを調べることが常に可能なので、そうでなければ不可能な操作であるようにはなりません。その目的のためにprocessableメソッドを使用する方がはるかにクリーンです。

+0

私はあなたが問題に遭遇したと思います: 'processable'メソッドが他の型で利用できる場合、' prepareOutput'メソッドが内部的にそれを呼び出すことが重要です。この観点から、 'prepareOutput'はとにかく' Optional 'を返さなければなりません。 –

1

は、なぜそれを異なるビットない

List<Ouput> execute(Input input) { 
    return simulations 
     .stream() 
     .map(s -> s.prepareOutput(input)) 
     .filter(Optional::isPresent) 
     .map(Optional::get) 
     .collect(Collectors.toList()); 
} 
+1

しかし、これは誰もが 'boolean processable(Simulation s、Input i){return s.prepareOutput(i).isPresent();というメソッドを書くことができるので、意味的にではなく、' processable'を技術的に隠すだけです。 } '、' processable'を隠している全てがこのテストを潜在的に効率の悪いものにしています。 – Holger

+1

@Holgerありがとう、良い点。私はその方法だけを隠していると思った。 + 1つはバルク処理の答えです。 – Eugene

関連する問題