5

例として、次のクラスがあるとします。

public class FruitBasket {
    private List<Apple> apples;
    private List<Orange> oranges;
    // getters and setters...
}

を取得するメソッドもどこかにあるとしFruitBasketます。

public FruitBasket getFruitBasket() {
    //...
}

さらに、getFruitBasketメソッドがプロキシ経由でアクセスされる 2 つの異なるソースからのデータを集約するとします。たとえば、AppleTree型のオブジェクトを取得Appleするサーバーと型のオブジェクトOrangeTreeを取得するサーバーがOrangeあり、どちらも というプロキシを介してアクセスされOrchardGateます。これがgetFruitBasketgetApplesアプリケーションgetOrangesからOrchardGate.

Appleオブジェクトとオブジェクトが正常に取得された場合、Orange問題はなく、FruitBasket. または の内部、またはとOrchardGateの両方にアクセスする際に問題が発生した場合は、 の子孫をスローすることでこれを処理することもできます(または、必要に応じて句に追加した場合でも)。AppleTreeOrangeTreeRuntimeExceptionExceptiongetFruitBasket throws

しかし、部分的な成功の場合はどうなるでしょうか。AppleTreeサーバーに問題なくアクセスできるのに、とOrangeTreeの間のトランスポートの問題が原因でサーバーにアクセスできない場合はどうなりますか?OrchardGateOrangeTree

私が見る限り、選択肢は 4 つしかなく、どれもまったくひどいものです。

  • Appleつまり、オブジェクトが正常に受信されたとしても、オブジェクトがFruitBasketないために返されないということOrangeです。
  • エラーを無視して、Orangeオブジェクトの空のリストを返すことができました。Orangeこれは、クライアントがオブジェクトを検索するときにエラーを確認できずOrange、サーバー上にオブジェクトが存在しないかのように見えることを意味しOrangeTreeます。
  • にアクセスするときに発生したエラーのリストを含むフィールドをFruitBasketcalledに追加できます。次に、発生したエラーを示すために呼び出されたリストにエラー コードを追加できます。ただし、このフィールドはドメイン オブジェクトにはまったく属していません。このフィールドは には関連しませんが、 を取得するトランザクションでのみ関連します。errorCodesFruitBasketPATH_FLOODEDerrorCodesFruitBasketFruitBasketFruitBasket
  • 例外をスローできますが、不完全なものを例外に添付しFruitBasketます。例外にはエラー情報のみを含める必要があり、フルーツ バスケットを含めてはならないため、これも恐ろしいことです。

この問題は Java で説明しましたが、この問題は複数の言語に及ぶと思います。私はそれについての議論をまだ見つけていないことに非常に驚いた. 部分的な成功を返すことができるメソッドを記述するための標準的なパターンはありますか? または私が逃したものはありますか?

4

3 に答える 3

1

このアプローチに問題はないと思います。

FruitBasket にアクセスするときに発生したエラーのリストを含む errorCodes というフィールドを FruitBasket に追加できます。次に、PATH_FLOODED というリストにエラー コードを追加して、発生したエラーを示します。ただし、このフィールド errorCodes は FruitBasket ドメイン オブジェクトにはまったく属していません。このフィールドは FruitBasket には関連しませんが、FruitBasket を取得するトランザクションでのみ関連します。

FruitBasketTransaction {
  FruitBasket fruitBasket;
  List<Error> errorCodes;

  // ... constructor and getters
}

public FruitBasketTransaction getFruitBasket() {
  // ...
}

// In your application somewhere
FruitBasketTransaction transaction = getFruitBasketTransaction();
if contains(transaction.errorCodes, APPLE_ERROR) {
  // ... tell the user
}
if contains(transaction.errorCodes, ORANGE_ERROR) {
  // ... tell the user
}

giveFruitToUser(transaction.getFruitBasket());
于 2015-08-11T08:06:10.960 に答える
1

loadFruitBasket()サーバーからAppleオブジェクトとOrangeオブジェクトをロードする別のメソッドが必要になると思い ます。りんごやみかんを入手するにはサーバーにアクセスする必要があるため、アクセスに成功した場合と失敗した場合のどちらを選択するかを設定booleanできます。次に、を使用する前に、FruitBasket をロードした Class にそれまたは. これにより、サーバーに何度もアクセスする必要がなくなり、さまざまなエラーを表示できます。truefalsegetFruitBasket()hasApples()hasOranges()

于 2015-09-18T13:28:25.853 に答える