『C++のためのAPIデザイン』レビュー


翻訳監修の三宅さん( @miyayou )さんから献本いただきました!ありがとうございます。


本書は、関数、クラス、ライブラリといった誰かに使ってもらうためのプログラムを書くプログラマのための本です。ほかの人に使ってもらうプログラムを書くために考えるべき多くのことが書かれています。たとえば、以下のようなことを考える必要があります:


ユーザーに公開するインタフェースはどうあるべきか。実装詳細はどれで、ユーザーは何を知っていれば十分なのか。それはどの場面で使用できるだろうか、いま目の前にある目的を達成できればいいのか、はたまた多くの場面で再利用したいのか。
バージョンに関しても考えなければいけない。このAPI後方互換性を保てるほど入念に考えられているだろうか。どうしても破壊しなければいけない場合、どういう設計選択をするべきか。
ドキュメントはどこまで書くべきだろうか。自動テストは何のために書くのか。


本書は、こういったAPI設計する上で行う多くの設計選択で参考になる、多くの画面での原則が解説されています。また、本書はC++を主言語として書かれてはいますが、これには現存するあらゆる言語に適用可能な知識が詰まっているので、他言語ユーザーの方にもぜひ読んでほしいです。


プロジェクトのソースコードというものは、資産であると同時に負債でもあります。そのソースコードは、リリース後のアップデートや機能追加のためにメンテナンスしていく必要があるので、リリースすることを最優先として書かれた、API設計があまり考えられていないフレームワークやアプリケーションコードはどこかで見直さなくてはなりません。そのリファクタリングや設計見直しのためのスクラッチという作業は、コード量が多ければ多いほど直すのが大変になります。どれくらい大変かというと、新機能の実装がしばらくの間できないくらい大変になるかもしれません。
API設計を初期から考えていくことは、長期的なスケジュールにおいてプラスの効果をもたらします。プロジェクトが常にクリーンなコードで作業でき、リリース直後から新機能の実装にとりかかれるようになるでしょう。
これはAPI設計がもたらす効果の一端にすぎません。本書にはこういったAPI設計がもたらす効果についてもしっかり書かれているので、ソースコードを書く技術者としてだけではなく、プロジェクトの体質を見直すために読んでみるのもいいと思います。


本書で扱っていない範囲についても書いておきましょう。この『C++のためのAPIデザイン』では広範な話題を扱っていますが、考えうる全てのことについて書かれているわけではありません。その扱っていないもののひとつに、「型」があります。
静的型付け言語では、型が多くの画面で役立ちます。型は関数のシグニチャから仕様を類推することを容易にし、プログラマが間違った使い方をしたときに事前にエラーにしてくれます。たとえば、以下は本書の1章で紹介されている暗号化クラスのコードです。(ドキュメンテーションコメントは省略します)

class StringEncryptor
{
public:
    void SetKey(const std::string& key);
    std::string Encrypt(const std::string& str) const;
    std::string Decrypt(const std::string& str) const;
};

これはシンプルで使いやすいインタフェースですが、ユーザーに間違えた使い方を許可してしまう可能性があります。暗号化を行う関数Encrypt()に暗号化済み文字列を渡したらどうなるだろうか。復号化を行うDecrypt()に復号化済み文字列を渡したらどうなるだろうか。これはドキュメントに自然言語で説明を書いて済ませる場合が大半だとは思いますが、型を活用することでこのインタフェースをもう少し強化してあげることができます。

class StringEncryptor
{
public:
    void SetKey(const std::string& key);
    encryped_string Encrypt(const decrypted_string& str) const;
    decrypted_string Decrypt(const encryped_string& str) const;
};

encryped_stringとdecrypted_stringはそれぞれ、暗号化された文字列、復号化された文字列であることを示す、強い型付けが施された文字列型であると考えてください。このような型を用意することにより、ユーザーは関数のシグニチャを一目見ただけで関数の挙動を類推することができるとともに、暗号化関数に暗号化済み文字列を渡したらコンパイルエラーにすることができます。


API設計にはまだまだ限界が見えません。
本書に載っている原則を身につけてより良いAPI設計ができるようになった方は、こういったさらなる良い設計のための原則を学んでいってください。そして、本書を読んだ方のなかから、新たなAPI設計や原則を生み出す方が出てくることを願っています。