C++17 例外の有無によるAPI設計分離レビュー|責務境界からレビューアーが設計の正当性を読み解く技術
この記事のポイント
- 例外有無でAPI設計をどう分離整理するかをレビューアーが読み解く技術を体系整理
- 契約整理・利用者責務・API境界設計をレビュー支援可能にする
- 現場レビューで「API粒度の設計崩壊」を防止する技術力を習得
そもそも例外有無によるAPI設計分離とは何か
C++では同じ処理内容でも、API契約設計として「例外有無でAPIを分ける」べき場面が多い。
| 例外利用API | 例外非利用API |
|---|---|
| 正常完了を原則前提 | エラーが通常パス |
| 例外 → 異常状態通知 | 戻り値でエラー返却 |
| 呼出側が例外安全責務を持つ | 呼出側が全分岐処理責務を持つ |
レビューアーは「このAPIは例外型契約で出すべきか?コード型で出すべきか?」を常に設計意図から読み解く必要がある。
なぜこれをレビューするのか
- API契約粒度が統一されず崩壊するケースが頻発
- 利用者責務が不明確化 → 保守事故の温床に
- 契約設計が属人文化に依存化しやすい
- レビュー段階でAPI契約を可視化整理できるレビュー文化が重要
レビューアー視点
- このAPIの主利用層は誰か?
- 呼び出し側が例外ハンドリング文化に合致する層か?
- 契約破綻 vs 予測可能系が契約で明文化されているか?
- 例外設計文化 or エラーコード設計文化どちらで統一するか?
- API境界毎に責務移譲整理が完了しているか?
開発者視点
- 公開API契約では例外有無を設計段階で固定宣言
- C++文化に沿う層は例外統一優先
- 組込・制御・移植対象層ではコード型統一
- 内部層封じ込めは例外→コード吸収層を設計
良い実装例
例1:例外統一API
例外統一API設計
void registerUser(const User& user) {
if (user.id <= 0) {
throw std::invalid_argument("Invalid user id");
}
if (!db.save(user)) {
throw DatabaseUnavailable("DB failure");
}
}- 契約破綻 → invalid_argument
- 外部障害 → custom exception
例2:エラーコード統一API
エラーコード統一API設計
enum class SaveResult {
Success,
ValidationError,
DBFailure
};
SaveResult registerUser(const User& user) {
if (user.id <= 0) return SaveResult::ValidationError;
if (!db.save(user)) return SaveResult::DBFailure;
return SaveResult::Success;
}- 全責務を戻り値に統一
レビュー観点
- API公開契約型に例外有無方針が統一宣言されているか
- 呼出層文化に適合する方式で設計されているか
- 設計ドキュメントに契約方針が固定宣言されているか
- 内部層は統一吸収層が存在するか
- 監視通知経路が例外有無に依存しない構成になっているか
良くない実装例: ケース1(API群で混在)
API間で統一崩壊
class UserService {
public:
void saveUser(const User& user); // 例外方式
SaveResult updateUser(const User& user); // エラーコード
@Reviewer同一責務API群内で例外/コード方式が混在しています。統一設計してください。
改善例
改善例(例外方式統一)
SaveResultを廃止し例外方式へ統一良くない実装例: ケース2(公開API崩壊)
公開API不統一
void apiEntry(User u) {
try {
service.save(u);
} catch (...) {
return SaveResult::DBFailure;
@Reviewer外部API契約型が例外有無で不統一です。公開契約は責務層に応じ統一してください。 }
}改善例
改善例(契約統一)
公開層ではSaveResult型APIで統一良くない実装例: ケース3(内部層崩壊)
内部吸収層不在
repository.save(); // 例外方式
dao.save(); // コード方式
@Reviewer内部層で例外吸収統一層が未設計です。統一Adapter層を設計追加してください。
改善例
改善例(吸収層整理)
repository層内部で例外→コード吸収層配置PlantUML:例外有無API責務整理図
API契約統一テンプレート
| 層分類 | 推奨方針 | 理由 |
|---|---|---|
| 外部公開API | コード方式 | 言語中立・安定契約 |
| 内部サービスAPI | 例外方式 | 設計自然文化維持 |
| デバイス層 | コード方式 | 組込文化適合 |
| 共通ライブラリ層 | 例外方式 | C++標準適合 |
レビューアーはこの表の選択根拠を毎回説明可能に整理する。
通知統一設計例
障害通知経路統一
try {
service.process();
} catch (const DatabaseUnavailable& e) {
monitoring.notify("DB_FAILURE");
} catch (...) {
monitoring.notify("FATAL");
}- 例外有無に関係なく通知整理可能
典型レビュー質問集
| 質問例 | 意図 |
|---|---|
| このAPIの利用者は例外文化に適合していますか? | 呼出層文化整合性確認 |
| API公開契約ドキュメントは統一されていますか? | 契約可視化確認 |
| 内部吸収層は整理されていますか? | 移植安全性確認 |
| モニタリング通知は統一経路化されていますか? | 運用性確認 |
レビューアーは契約文化統一支援レビュー文化を現場で確立する。
観点チェックリスト
まとめ
レビューアーがAPI契約分離レビューで常に問うべきは
「このAPI契約は誰がどう利用し、文化として統一されているか?」
です。
- API文化 → 設計層別文化宣言
- 統一契約 → 契約型ドキュメント宣言
- 吸収層文化 → 内部封じ込め層整理
- 運用文化 → 通知経路統一
レビュー現場では
「API契約文化をレビュー文化で早期確定させる」
ことで長期品質と設計安定性が保証されます。
