私は、同期操作と非同期操作の両方を公開するC++ APIを設計しています。すべての操作が失敗し、失敗を報告する必要があります。非同期操作は、完了時に継続を実行する方法を提供する必要があります。私は最も読みやすく一貫した方法でAPIを設計しようとしています。同期操作と非同期操作を組み合わせたC++ API用の設計
これが今の私が持っているデザインを示す一例である:
#include <memory>
#include <future>
using namespace std;
class Error {
public:
Error(int c, string desc) : code(c), description(desc) {}
int code;
string description;
};
template<typename T>
class Callback {
public:
virtual void completed(const T& result, unique_ptr<Error> error) = 0;
};
template<typename T>
class PrintCallback : public Callback<T> {
public:
void completed(const T& result, unique_ptr<Error> error) override {
if (nullptr != error) {
printf("An error has occured. Code: %d Description: %s\n",
error->code, error->description.c_str());
} else {
printf("Operation completed successfully. Result: %s\n",
to_string(result).c_str());
}
}
};
class API {
public:
void asyncOperation(shared_ptr<Callback<int>> callback) {
thread([callback]() {
callback->completed(5, nullptr);
}).detach();
}
int syncOperation(unique_ptr<Error>& error) {
return 5;
}
void asyncFailedOperation(shared_ptr<Callback<int>> callback) {
thread([callback]() {
callback->completed(-1, unique_ptr<Error>(new Error(222, "Async Error")));
}).detach();
}
int syncFailedOperation(unique_ptr<Error>& error) {
error = unique_ptr<Error>(new Error(111, "Sync Error"));
return -1;
}
};
私は同期操作用のエラー出力パラメータの使用の使用と同期および非同期の署名の間に矛盾が好きではありません。彼らは非同期であり、彼らは彼らによって結果/失敗を返すためにコールバックを受け入れてみましょうかのように
- トリート同期操作: は、私は2つの選択肢を議論しています。このアプローチは、同期操作と非同期操作の間でより一貫性があり、少し洗練されています。一方、シンプルな同期操作をCallbackと連携させるのはちょっと変わった感じです。
std::promise
とstd::future
を使用し、例外を使用して障害を報告してください。非同期操作では、std::future
が返され、get()
が失敗した場合にスローされます。同期操作では、障害が発生した場合にスローされます。このアプローチは、エラー処理がメソッドシグニチャをクラッタさせず、例外がC++でのエラー処理を行う標準的な方法であるため、はるかにきれいに感じます。しかし、結果を得るにはfuture::get()
に電話しなければならないので、ブロックしたくなければ、別のスレッドを起動して結果を待たなければなりません。また、非同期オペレーションの継続が実際にstd::promise
の結果を設定するスレッド上で実行されることも重要です。このアプローチは、この質問に受け入れられた答え - Synchronous and ASynchronous APIsです。
私は思ったんだけど:代替#2内の余分なスレッドを回避できる場合
- 。
- 代替案#2の反対がその賛否(特に余分なスレッド)よりも重要な場合。
- 私が考えていない別のアプローチがある場合。
- どのアプローチが可読性と一貫性のための最良の選択肢と考えられるでしょうか。
ありがとう!
これは、Stack Overflowの問題が広すぎるためです。あなたは、APIデザインに関する書籍全体を書くことができます! :)しかし、私はニットを1つ持っています:* "例外はC++でエラー処理を行う標準的な方法です" * - いいえ、そうではありません。コンテキストに応じて、エラーコードやアサーションはしばしばよりクリーンです。 –
[codereview.se]サイトは、既存の作業コードの改善に関する質問に適しています。 [ヘルプセンター](// codereview.stackexchange.com/help/on-topic)に相談した上で、そこに移行するためにあなたの質問にフラグを立てることをお勧めします。 –
@ChristianHackl私はこれがかなり設計上の問題であると感じています。エラー処理に関する非同期メソッドと同期メソッドの間に一貫性の問題を提示しようとしました。ここでは、それを解決する方法(さまざまな選択肢)とそれらに対する私の懸念がありました。 – galsh83