トップ «前の日記(2009-10-02) 最新 次の日記(2009-10-04)» 編集

日々の破片

Subscribe with livedoor Reader
著作一覧

2009-10-03

_ コード補完時代にAPIはどうあるべきか?

さて(承前)、実は問題は、LogLogのメソッドシグネチャにある。少なくともおれは、そう考える。

おれは常識人だし、みなさんも良識の持ち主だ。

こういう人たちは、以下のようなメソッドをオーバーロードするときに、どう定義するだろうか?

  • エラー用のログ出力メソッド。当然、ログファイルに出力するメッセージは引数に必要。
  • でも、例外くらった場合は、例外オブジェクトを引数に付けてくれればメッセージとかスタックトレースとかもログするよ。そのほうがいいよね。

それは、もう、こうするだろう。

interface Log {
    public void error(String msg);
    public void error(String msg, Throwable t);
}

なぜならば、Throwable tはあるかないかわからない、つまりはオプションだからだ。デフォルト引数が取れるプログラミング言語なら、次のようになるし、多くのプログラミング言語でもデフォルト引数は最後に配置するように実装上の都合から作られている(C++など)。

class Log
  def error(s, e = nil)
    ..
  end
end

それに対して、msg引数は文句なく主役だし、常にそこに存在するし、オーバーロードしたメソッドで同じ意味を持つ引数は同じ位置にあるべきだからだ。

だが、それは常識が通用していた時代の発想だ。

今は、常識が通用しない時代だ。

だって、JavaはLL(by ひがやすお)なんだぜ。そのくらい常識は地に落ちているのだ。

だから、上のAPIはだめだ。全然お話にならない。

コード補完を意識してAPIを決めることが正しい。

logger. と打ったときに、errorと出てくる。

型名や、仮引数名でソートされる可能性も忘れてはならない。

ThrowableのTは、StringのSより下位だし、msgのmよりtのtは後だ。

最初に選ばれるものを重視し、それにあった型と名前を選択する。

つまり、以下のようにインターフェイスをきる。

interface Log {
    public void error(Exception e, String msg);
    public void error(String msg);
}

というか、ExceptionがThrowableだとわかっていない開発者が紛れる可能性も考慮したほうが良いからExceptionと型指定すべきだ(実際問題としてErrorやThrowableを扱う必然はほとんどないから、知らなくても構わない)。

引数が少ない順にソートするIDEをもし使っていて、かつその表示順序を変えられないなら、以下のようにする。

interface Log {
    public void error(Exception e, String msg);
    public void error(String msg, String auxmsg); // auxmsg(補足情報)はnullでも可
}

デバッグ用出力メソッドも用意するか、と考える。

interface Log {
    public void debug(Exception e, String msg);
    public void debug(String msg, String auxmsg); // auxmsg(補足情報)はnullでも可
    public void error(Exception e, String msg);
    public void error(String msg, String auxmsg); // auxmsg(補足情報)はnullでも可
}

だめだ、それはだめだ。メソッドはアルファベット順にソートされて補完ウィンドウに出てくるのが常識だ。

したがって、debugはerrorより下に出さなければ、重要なログがデバッグ扱いされる危険がある。

interface Log {
    public void error(Exception e, String msg);
    public void error(String msg, String auxmsg); // auxmsg(補足情報)はnullでも可
    // さらに定義順の可能性も考慮して、重要度が低いものは下に配置する。
    public void putDebug(Exception e, String msg);
    public void putDebug(String msg, String auxmsg); // auxmsg(補足情報)はnullでも可
}

Eclipse時代のAPIでは、何がなんでも、どんな手段を使っても、優先順位が低いメソッドは、下になるように配置するのだ。

ここで、メソッド名の一貫性が失われる! と考えるのは、過去の常識人だ。本末転倒人でもある。

なぜ一貫性が必要かといえば、覚えやすいからだ。覚えやすいからコーディング効率は良いし、間違いも少なく、初回コンパイルエラーとかに遭遇もしにくくなる。でも、覚えなくてもいいようにコード補完があるのだし、コード補完されたメソッド名を選択するのだから書き間違いに関することは念頭に置く必要は、まったくもってない。ここで重要なのは、重要度が落ちるメソッドは下になる=選択しにくくすることにある。

というように、プロジェクトが望む方向に開発者が自然とコードを書けるように、ツールの力を借りているのであれば、それを、より推進する方向でAPIを考えることが必要であり、必然となる。

さて、Eclipse大好きな諸子、そこまで意識してEclipseを使っていますか?

注:昨日のはともかく、上で書いているのは相当まじめな論議で、主となるツールに合わせて、設計者の意図に沿ったコードが自然に書けるようにAPIを考えろ、ということだ。そのためなら、LogLogを内包したおれさまログラッパーインターフェイスを提供して、そいつをインポートさせるというのが正しいと考えている。今となっては。

_ 世界一のマンガ

本屋行ったら、朝倉世界一の新刊が出てたから買った。これから読む。

デボネア・ドライブ 2 (BEAM COMIX)(朝倉 世界一)

帯のジャック(正しい読みはなんなんだ? 後で調べる)を江口寿志が書いているってことは、既におっさんほいほいになってしまったのか。

でもおれにとっては朝倉世界一は、今だって、世界一モダンな漫画家なんだけどな。でも、ヘタウマ文脈で考えりゃ、すでに30年近いことになるのか。そりゃおっさんほいほい系だよなぁ。

というか、ガロ−パンチザウルス−白夜のいろいろの流れでうじゃうじゃ出てきた中で、岡崎京子と並んで朝倉世界一は、独特なセンチメンタルさと冷酷さの入り混じり具合がおれにはすげぇフィットしていて、今でも好きだ。

アポロ (Cue comics)(朝倉 世界一)

アポロなんて、セリフを覚えるほど読み込んだものだ。嘘(大げさの意味)だけど。

心臓が弱い(走ると動悸が乱れて死にそうになる)ロボくんが主人公で、アトムをほんの少し設定上でパロディにしていて(親捜しとか最後の消滅とか胸の蓋をぱかっと開けるとかも、多分)、主人公との奇妙な出会いと友情(このへんはオバQっぽい)とか、60年代スパイアクションの乗り(しかし絵は80年代どまんなか)とか、一コマ一コマに才能が迸っている(というか、結局、おれの好みにどんぴしゃりということだが)すごい作品だ。というか、今書いていて気付いたが、60年代の子供マンガの世界を80年代モダンで脱構築しているということか。それはどんぴしゃなのは当然だな。

敵のアジトのアパートの上の階に引っ越して、毎晩ダンスを踊ったり足踏みしたりして、寝不足攻撃をかけるとか、今でも好きなギャグだよな。

で、良くみたら、「2」とか書いてあって、1もあるのか。知らなかったので、後で買う。

デボネア・ドライブ 1 (BEAM COMIX)(朝倉 世界一)


2003|06|07|08|09|10|11|12|
2004|01|02|03|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|04|05|06|07|08|09|10|11|12|
2012|01|02|03|04|05|06|07|08|09|10|11|12|
2013|01|02|03|04|05|06|07|08|09|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|05|06|07|08|09|10|11|12|
2016|01|02|03|04|05|06|07|08|09|10|11|12|
2017|01|02|03|04|05|06|07|08|09|10|11|12|
2018|01|02|03|04|05|06|07|08|09|10|11|12|
2019|01|02|03|04|05|06|07|08|09|10|11|12|
2020|01|02|03|04|05|06|07|08|09|

ジェズイットを見習え