19-誰にとっての「利便性」か

プログラマが知るべき97のこと」の19個目のエピソードは、APIのデザインに関する話題です。API(Application Program Interface)はその名前の通りインターフェイスです。インターフェイスとは、複数の異なるものの間で情報をやりとりする取り決めです。プログラムのインターフェイスであれば、利用するプログラムと利用されるプログラムの間で情報をやりとりするために定義された関数やメソッドです。情報は引数や戻り値としてやりとりされます。
このエピソードでは、初めにAPIを作る時に陥りやすい罠を示唆しています。プログラマならば、コードを書いていく中で、冗長性を省いたり、複数の操作を1つにまとめて整合性をとったり、美しさを求めて情報を隠蔽したりします。一般的にそれは正しい事ですが、作成しているプログラムがAPIとして公開されるならば、呼び出す側にとっての利便性を考慮すべきです。

APIを作るというのは、複雑な処理を隠蔽するということです。

特にオープンソース等でAPIを公開して誰かに利用して貰いたい場合や普段一緒に仕事をしていないメンバーにAPIを提供するような場合では、APIの利便性が重要な要素となります。APIを利用する人は、面倒な処理を簡単に行いたいのです。言い換えれば、自分の作るべきプログラムに集中したいのであって、APIの使い方を研究・解析したいとは思いません。内部の実装まで確認しなければ何をやっているのか解らないのは論外ですが、少なくともAPIのドキュメントを読めば理解できる必要があります。そうでなければ、APIを提供しても利用して貰えません。したがって、APIが使いやすいかを利用者の立場に立って考えるべきです。
少なくとも使いにくいAPIを作らない為の手法があります。TDD(テスト駆動開発)です。TDDの場合、先にAPIを使う為のコードをテストコードとして作成します。これは、APIの開発者が最初の利用者になると言うことです。自分で使いにくいな、と思ったAPIが他のプログラマから評価されるわけありません。テストが書きやすく、かつ読みやすければ、少なくとも使いにくいAPIとはならないでしょう。テストコードはAPIを利用するサンプルコードにもなります。
また、「こんなシチュエーションがあるはずだろう」と想像することも大切です。APIを設計する場合は利用シーンを想定することは重要です。このAPIを使うときに「文字コードを指定したくなるのではないか?」「この処理は再帰的に処理するパターンと、同一階層だけ処理したい場合の2パターンがあるだろう」などです。プログラミングの原則の1つにYAGNI(You Aren't Going to Need It./それ、たぶん要らない)というものがあります。これは必要だろうと思って作った物も使う事はほとんどないため、必要になってから作ろうという教えです。しかし、APIの場合は痒い所まで考慮されている方が評価が高くなるので注意が必要です。

より良いAPIを作るには、APIを1つの言語だと考えるといいと思います。

APIを1つの言語として考えることは大切です。コードの可読性については幾つものエピソードで語られていますが、APIが残念なデザインであると、美しいコードとなりません*1

  player.walk(true);
  player.walk(false);

フラグはぱっと見て解りません。

  player.logic020();
  player.logic041();

「いんたーふぇいすせっけいしょ」を開かないと何のロジックか想像もできません。

  player.walk();
  player.run();

runはwalkと実装がほとんど一緒ですし、内部的には次のようになっているかもしれませんが、公開されたAPIはシンプルでやりたい事がダイレクトに伝わります。

public class Player {
   public void walk() {
     walk(true);
   }
   public void run() {
     walk(false);
   }
   private void walk(boolean isRun) {
     // 実装
   }   
}

APIを設計する時には、ボキャブラリーに多様性を持たせることで表現豊かなコードを利用者が書く事ができるでしょう。その為のリファクタリングも忘れずに。
尚、自分ならば、このように書ける事を選択します。

  player.walk();
  player.walkFast();

Java使いならば、Eclipseが補完してくれることも考慮すると良いと思います。

プログラマが知るべき97のこと

プログラマが知るべき97のこと

*1:その為、強引にラップすることもありますが・・・