Singleton の憂鬱

パターンを覚え始めた頃は、Singleton ばかり使っていました。引数で渡す手間なしに、いつでもどこからでもオブジェクトにアクセスできる。なんて便利なんだと。

しかし最近になって、Singleton がやけに鬱陶しくなってきたのです。

たぶんそれは、中毒のような依存性があちこちに発生することへの嫌悪感から来ています。ゲリラ的なアクセスを見て見ぬフリをするような、後ろめたい気持ち、敗北感のようなものがあるのです。この戦略は間違っているのではないか。

Singleton はまた、テストにも手間がかかります。Singleton に依存したオブジェクトをテストする時には、Singleton を正しくセットアップする必要があります。でも、Singleton にするのは大抵、生成コストが高かったり、メモリを大量に消費するような、鈍重で扱いが面倒なオブジェクトであることが多い。そうすると、手っ取り早くテストしたい気持ちにブレーキがかかる。本質的でないところで時間を取られる。気分が沈む。全然嬉しくない。

おそらく、長い目で見たら Singleton を撤廃したほうが幸せになれる。そのかわり、インタフェースオブジェクトとデリゲートオブジェクトのペアを管理するようにする。

class FooDelegate {
public:
    virtual ~FooDelegate() {}
    virtual void FooWork() = 0;
};

class Foo {
    FooDelegate* delegate_;

public:
    Foo(FooDelegate* delegate);
    void Work();
};

Foo に依存するオブジェクトをテストする時には、FooDelegate を用意する。FooDelegate のインスタンスは本番ではシングルだけど、テストではマルチでも構わない。シングルにするなら参照カウンタでも使って共有すれば良い。いずれにせよ大事なことは単純な関係を保ち、特殊な条件を押しつけないことだと思う。

一方で、ここまで手間をかけて Singleton を除去する必要があるのかという迷いもある。だけど、Singleton が増えるごとに借金が増えていくような嫌な気分を味わうくらいなら、これくらいのコストは進んで払いたい。

さらば、Singleton。となれば良いのだけれど。

新エンジンの進捗

暗黙的なサーバー補完をサポートしました。見出し語の補完でユーザー辞書以外の一般辞書も対象にできます。この結果、L 辞書には含まれるけれど、まだ一度も変換したことのない候補も補完できるようになりました。妙な引っ掛かりも感じないので、地味ですがいい機能だと思います。

また、Leopard ではドキュメント毎に入力モードを保持するオプションが消滅したため、AquaSKK 内部でこれをサポートするようにしてみました。入力モードを変更した時や Ctrl-L で、現在の入力モードがカーソル位置に表示されます。

http://aquaskk.sourceforge.jp/videos/inputmode.swf

フェードアウトは無駄に Core Animation を使っています。このあたりの話もいつか書こうと思います。