この記事のポイント

  • ソート済み状態を誰がどこで保証するかをレビューアー視点で整理
  • API契約整理、二重ソート防止、性能最適化、安全設計のレビュー観点を体系化
  • 責任分離文化育成のレビュー技術を養成

そもそもソート済み保証とは

ソート済みデータ保証とは「このデータは常に特定の順序で並んでいることを前提に処理して良い」という設計責任を指します。

  • 検索最適化 (lower_bound, binary_search)
  • 重複排除 (unique適用前提)
  • マージ最適化 (merge)
  • 保証責任が曖昧だと意図しない不整合バグを誘発
  • レビューで設計段階から責任整理を徹底する

なぜこれをレビューするのか

レビューアー視点

ソート保証設計レビューは以下の責任整理が求められます。

  • 保証責任明文化
    → ソート済み状態の保持主体を明確化

  • API契約整理責任
    → 呼出側・API内部いずれが保証するか契約に明記

  • 性能設計責任
    → ソート済み前提でのlower_bound等の適用可否整理

  • 二重ソート防止責任
    → ソート過剰適用のコスト管理

  • 整合性保証責任
    → ソート破壊操作後の再保証責任整理

開発者視点

  • ソート実施責任の意識薄弱
  • API設計で保証責任未整理
  • 呼出側が毎回ソートする文化
  • lower_bound等の適用前提崩壊
  • ソート破壊操作後の整合性放置

レビューアーはこれら「責任未整理文化」をレビュー段階で整理・是正します。

良い実装例(内部保証型設計)

ユースケース:APIレスポンスを時系列順に維持

良い実装例:API内部でソート保証保持
#include <vector>
#include <algorithm>

struct ApiRequestLog {
    std::string requestId;
    time_t requestedAt;

    bool operator<(const ApiRequestLog& other) const {
        return requestedAt < other.requestedAt;
    }
};

class ApiRequestLogRepository {
public:
    void add(const ApiRequestLog& log) {
        auto pos = std::lower_bound(logs_.begin(), logs_.end(), log);
        logs_.insert(pos, log);
    }

    const std::vector<ApiRequestLog>& getSortedLogs() const {
        return logs_;
    }

private:
    std::vector<ApiRequestLog> logs_;
};
  • 追加時に常にソート保証を維持
  • 呼出側はソート済み前提で利用可能
  • lower_bound適用可能文化が安全に確立

レビュー観点

  • ソート保証が呼出側ではなくAPI内に統合されているか
  • lower_bound等の利用前提が明文化されているか
  • ソート破壊操作(erase, insert等)が保証を壊していないか
  • 保持責任者がレビュー時に明示されているか

良くない実装例: ケース1

以下は呼出側が毎回ソート責任を持ってしまっている例。

呼出側多重ソート例
auto logs = repository.getLogs();
std::sort(logs.begin(), logs.end());
@Reviewer
ソート責任が呼出側に放置されています。API内で保証を内包してください。

問題点

  • API設計として責任放棄
  • 利用者ごとに重複処理発生

改善例

修正例:内部保証設計
class ApiRequestLogRepository { /* 前掲例の通り */ };

良くない実装例: ケース2

次はlower_bound利用前提でソート保証が曖昧な例。

lower_bound前提崩壊例
auto it = std::lower_bound(logs.begin(), logs.end(), target);
@Reviewer
ソート保証が事前に成り立つ契約整理が設計段階で未整理です。

問題点

  • ソート破壊時にlower_bound適用がバグ源化
  • 設計責任不在

改善例

修正例:保証責任整理
add()で常時ソート順投入設計へ移行

良くない実装例: ケース3

次はAPI契約でソート保証有無が不透明な例。

ソート保証不透明API例
const std::vector<ApiRequestLog>& getLogs() const;
@Reviewer
返却契約でソート保証有無が明文化されていません。契約文書で保証範囲を明確化しましょう。

問題点

  • 保証有無を呼出側が暗黙期待
  • 保守困難化

改善例

修正例:契約文書明文化
「返却順はrequestedAt昇順保証」とAPI設計文化に明記

ソート保証設計パターン整理

パターンA:API内部保証型(推奨文化)

  • 保持側が常に整列責任維持
  • 呼出側は保証前提利用可能

パターンB:呼出側責任委譲型(限定文化)

  • 性能特性上事前並列構築時のみ限定利用
  • API契約に責任委譲を明文化

ソート保証責任整理フレームワーク

項目 保持責任者
新規追加操作 API内部
取得操作 呼出側
lower_bound適用可否 保証文書化

PlantUMLで設計責任整理

UML Diagram

観点チェックリスト

実務レビューFAQ

Q1. 呼出側ソートは常に悪?
→ 安定API設計文化では原則排除。性能特化APIは限定許容。

Q2. lower_bound使用前提の危険は?
→ 保証不在なら誤答発生。レビューで契約保証整理必須。

Q3. 二重ソートは何が無駄?
→ 処理負荷増・バグ埋没・文化崩壊。

Q4. ソート保証文化は組織設計文化?
→ まさに設計文化の本丸領域。レビュー育成対象。

Q5. 順序保証とソート保証は同じ?
→ 関連だが非同一。順序保証は挿入順、ソート保証は順序定義済。

まとめ

ソート保証レビューは安定品質設計文化の中心教材である。
レビューアーは

  • 保持責任整理
  • lower_bound適用前提保証
  • API契約安定化責任
  • 保守性保証設計責任

を読み解き、「安定は責任整理から生まれる」レビュー技術を育成する必要がある。
レビューアーがソート保証設計レビューを体系化できると設計品質は長期安定する。